Index: Core/Components/src/Core.Components.BruTile.Data/BruTileSettings.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.Data/BruTileSettings.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile.Data/BruTileSettings.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,73 @@ +// 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 BruTile.Cache; +using Core.Common.Gui.Settings; + +namespace Core.Components.BruTile.Data +{ + /// + /// Class holding BruTile related settings. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/BruTileLayerSettings.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public static class BruTileSettings + { + /// + /// Gets a value indicating the maximum number of threads used for retrieving + /// map tiles. + /// + public static int MaximumNumberOfThreads { get; } = 4; + + /// + /// Gets a value indicating which format should be used to store the tiles. + /// + public static string PersistentCacheFormat { get; } = "png"; + + /// + /// Gets a value indicating how long tiles remain valid. + /// + public static int PersistentCacheExpireInDays { get; } = 14; + + /// + /// Gets the value + /// + public static int MemoryCacheMinimum { get; } = 100; + + /// + /// Gets the value + /// + public static int MemoryCacheMaximum { get; } = 200; + + /// + /// Gets the root directory path for the persistent cache. + /// + public static string PersistentCacheDirectoryRoot + { + get + { + return SettingsHelper.Instance.GetApplicationLocalUserSettingsDirectory("tilecaches"); + } + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.Data/Core.Components.BruTile.Data.csproj =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.Data/Core.Components.BruTile.Data.csproj (revision 0) +++ Core/Components/src/Core.Components.BruTile.Data/Core.Components.BruTile.Data.csproj (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,70 @@ + + + + + {3DCEF8F6-CB6D-435C-9539-50143DACD86C} + Library + Properties + Core.Components.BruTile.Data + Core.Components.BruTile.Data + v4.0 + 512 + + + true + full + false + DEBUG;TRACE + prompt + + + none + true + TRACE + prompt + + + TRACE + true + true + pdbonly + prompt + AllRules.ruleset + + + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + + + + + Properties\GlobalAssembly.cs + + + + + + + Copying.Lesser.licenseheader + + + + + + {30E4C2AE-719E-4D70-9FA9-668A9767FBFA} + Core.Common.Gui + False + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.Data/Properties/AssemblyInfo.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.Data/Properties/AssemblyInfo.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile.Data/Properties/AssemblyInfo.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ +// 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Core.Components.BruTile.Data")] +[assembly: AssemblyProduct("Core.Components.BruTile.Data")] +[assembly: Guid("3dcef8f6-cb6d-435c-9539-50143dacd86c")] \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.Data/packages.config =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.Data/packages.config (revision 0) +++ Core/Components/src/Core.Components.BruTile.Data/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.Forms/BrutileWmtsCapabilityFactory.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.Forms/BrutileWmtsCapabilityFactory.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile.Forms/BrutileWmtsCapabilityFactory.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,56 @@ +// 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.Collections.Generic; +using BruTile; +using BruTile.Wmts; +using Core.Components.BruTile.Configurations; +using Core.Components.Gis.Exceptions; +using Core.Components.Gis.Forms; + +namespace Core.Components.BruTile.Forms +{ + /// + /// Class responsible for creating instances for a given + /// source. + /// + public class BruTileWmtsCapabilityFactory : IWmtsCapabilityFactory + { + /// + /// Returns all based on the capabilities of a Web Map Tile Service. + /// + /// The URL to the 'GetCapabilities' part of the service. + /// The WMTS capabilities. + /// Thrown when unable to retrieve + /// tile sources from the given service. + public IEnumerable GetWmtsCapabilities(string capabilitiesUrl) + { + IEnumerable tileSources = TileSourceFactory.Instance.GetWmtsTileSources(capabilitiesUrl); + + foreach (var tileSource in tileSources) + { + var wmtsTileSchema = (WmtsTileSchema) tileSource.Schema; + yield return new WmtsCapability(wmtsTileSchema.Identifier, wmtsTileSchema.Format, + tileSource.Name, wmtsTileSchema.Srs); + } + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.Forms/Core.Components.BruTile.Forms.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.BruTile.Forms/Core.Components.BruTile.Forms.csproj (.../Core.Components.BruTile.Forms.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/src/Core.Components.BruTile.Forms/Core.Components.BruTile.Forms.csproj (.../Core.Components.BruTile.Forms.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -32,6 +32,10 @@ AllRules.ruleset + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + @@ -40,12 +44,30 @@ Properties\GlobalAssembly.cs + Copying.Lesser.licenseheader + + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + False + + + {4A06DF0D-5D75-4BAD-A95A-A3DB9B7C4AD5} + Core.Components.Gis.Forms + False + + + {318BA582-88C9-4816-A54A-A7E431461DE3} + Core.Components.Gis + + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.IO/AsyncTileFetcher.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.IO/AsyncTileFetcher.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile.IO/AsyncTileFetcher.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,283 @@ +// 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.Concurrent; +using System.Threading; +using Amib.Threading; +using BruTile; +using BruTile.Cache; +using Core.Components.BruTile.Data; +using Core.Components.BruTile.IO.Properties; + +namespace Core.Components.BruTile.IO +{ + /// + /// Class responsible for fetching map tiles asynchronously from a . + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/TileFetcher.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public class AsyncTileFetcher : ITileFetcher + { + private readonly ConcurrentDictionary activeTileRequests = new ConcurrentDictionary(); + private readonly ConcurrentDictionary openTileRequests = new ConcurrentDictionary(); + private ITileProvider provider; + private MemoryCache volatileCache; + private ITileCache persistentCache; + private SmartThreadPool threadPool; + + public event EventHandler TileReceived; + + public event EventHandler QueueEmpty; + + /// + /// Creates an instance of . + /// + /// The tile provider. + /// Minimum number of tiles in memory cache. + /// Maximum number of tiles in memory cache. + /// Optional: the persistent cache. When null, no tiles + /// will be cached outside of the volatile memory cache. + /// Throw when + /// is null. + /// Thrown when either + /// or is negative. + /// Thrown when + /// is not smaller than . + public AsyncTileFetcher(ITileProvider provider, int minTiles, int maxTiles, ITileCache permaCache = null) + { + if (provider == null) + { + throw new ArgumentNullException(nameof(provider)); + } + if (minTiles < 0) + { + throw new ArgumentOutOfRangeException(nameof(minTiles), Resources.AsyncTileFetcher_Number_of_tiles_for_memory_cache_cannot_be_negative); + } + if (maxTiles < 0) + { + throw new ArgumentOutOfRangeException(nameof(maxTiles), Resources.AsyncTileFetcher_Number_of_tiles_for_memory_cache_cannot_be_negative); + } + if (minTiles >= maxTiles) + { + throw new ArgumentException(Resources.AsyncTileFetcher_Minimum_number_of_tiles_in_memory_cache_must_be_less_than_maximum); + } + + this.provider = provider; + volatileCache = new MemoryCache(minTiles, maxTiles); + persistentCache = permaCache ?? NoopTileCache.Instance; + threadPool = new SmartThreadPool(10000, BruTileSettings.MaximumNumberOfThreads); + } + + public byte[] GetTile(TileInfo tileInfo) + { + ThrowExceptionIfDisposed(); + + byte[] res = GetTileFromCache(tileInfo); + if (res != null) + { + return res; + } + + ScheduleTileRequest(tileInfo); + return null; + } + + public bool IsReady() + { + ThrowExceptionIfDisposed(); + + return activeTileRequests.Count == 0 && openTileRequests.Count == 0; + } + + public void DropAllPendingTileRequests() + { + ThrowExceptionIfDisposed(); + + // Notes: http://dotspatial.codeplex.com/discussions/473428 + threadPool.Cancel(false); + int dummy; + foreach (var request in activeTileRequests.ToArray()) + { + if (!openTileRequests.ContainsKey(request.Key)) + { + if (!activeTileRequests.TryRemove(request.Key, out dummy)) + { + activeTileRequests.TryRemove(request.Key, out dummy); + } + } + } + openTileRequests.Clear(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (IsDisposed) + { + return; + } + + if (disposing) + { + volatileCache.Clear(); + + threadPool.Dispose(); + threadPool = null; + + volatileCache = null; + provider = null; + persistentCache = null; + } + + IsDisposed = true; + } + + private bool IsDisposed { get; set; } + + /// + /// Thrown an when + /// is true. + /// + /// Thrown when calling this method while + /// this instance is disposed. + private void ThrowExceptionIfDisposed() + { + if (IsDisposed) + { + throw new ObjectDisposedException(GetType().Name); + } + } + + private byte[] GetTileFromCache(TileInfo tileInfo) + { + TileIndex index = tileInfo.Index; + return volatileCache.Find(index) ?? persistentCache.Find(index); + } + + private void ScheduleTileRequest(TileInfo tileInfo) + { + if (!HasTileAlreadyBeenRequested(tileInfo.Index)) + { + activeTileRequests.TryAdd(tileInfo.Index, 1); + var threadArguments = new object[] + { + tileInfo + }; + threadPool.QueueWorkItem(GetTileOnThread, threadArguments); + } + } + + private bool HasTileAlreadyBeenRequested(TileIndex tileIndex) + { + return activeTileRequests.ContainsKey(tileIndex) || openTileRequests.ContainsKey(tileIndex); + } + + /// + /// Method to actually get the tile from the . + /// + /// The thread parameters. The first argument is the + /// for the file to be fetched. + private void GetTileOnThread(object[] parameters) + { + var tileInfo = (TileInfo) parameters[0]; + GetTileOnThreadCore(tileInfo); + } + + private void GetTileOnThreadCore(TileInfo tileInfo) + { + if (!Thread.CurrentThread.IsAlive) + { + return; + } + byte[] result = TryRequestTileData(tileInfo); + + MarkTileRequestHandled(tileInfo); + + if (result != null) + { + volatileCache.Add(tileInfo.Index, result); + persistentCache.Add(tileInfo.Index, result); + + OnTileReceived(new TileReceivedEventArgs(tileInfo, result)); + } + } + + private byte[] TryRequestTileData(TileInfo tileInfo) + { + byte[] result = null; + try + { + openTileRequests.TryAdd(tileInfo.Index, 1); + result = provider.GetTile(tileInfo); + } + catch {} + + //Try at least once again + if (result == null) + { + try + { + result = provider.GetTile(tileInfo); + } + catch {} + } + return result; + } + + private void MarkTileRequestHandled(TileInfo tileInfo) + { + int dummy; + if (!activeTileRequests.TryRemove(tileInfo.Index, out dummy)) + { + //try again + activeTileRequests.TryRemove(tileInfo.Index, out dummy); + } + if (!openTileRequests.TryRemove(tileInfo.Index, out dummy)) + { + //try again + openTileRequests.TryRemove(tileInfo.Index, out dummy); + } + } + + private void OnTileReceived(TileReceivedEventArgs tileReceivedEventArgs) + { + TileReceived?.Invoke(this, tileReceivedEventArgs); + + if (IsReady()) + { + OnQueueEmpty(EventArgs.Empty); + } + } + + private void OnQueueEmpty(EventArgs eventArgs) + { + QueueEmpty?.Invoke(this, eventArgs); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.IO/Core.Components.BruTile.IO.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.BruTile.IO/Core.Components.BruTile.IO.csproj (.../Core.Components.BruTile.IO.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/src/Core.Components.BruTile.IO/Core.Components.BruTile.IO.csproj (.../Core.Components.BruTile.IO.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -9,6 +9,8 @@ Core.Components.BruTile.IO v4.0 512 + + true @@ -32,21 +34,63 @@ AllRules.ruleset + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + ..\..\..\..\packages\SmartThreadPool.dll.2.2.4\lib\net40\SmartThreadPool.dll + True + + + ..\..\..\..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net40\System.Data.SQLite.dll + True + Properties\GlobalAssembly.cs + + + + + True + True + Resources.resx + + Copying.Lesser.licenseheader + + + + {3DCEF8F6-CB6D-435C-9539-50143DACD86C} + Core.Components.BruTile.Data + False + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Het minimale aantal kaart tegels voor de geheugen cache moet kleiner zijn dan het maximale aantal kaart tegels. + + + Het aantal kaart tegels voor de geheugen cache moeten positief zijn. + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.IO/TileReceivedEventArgs.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.IO/TileReceivedEventArgs.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile.IO/TileReceivedEventArgs.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,67 @@ +// 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 BruTile; + +namespace Core.Components.BruTile.IO +{ + /// + /// Event arguments for denoting the event that a new tile has been received. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/TileReceivedEventArgs.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public class TileReceivedEventArgs : EventArgs + { + /// + /// Creates an instance of . + /// + /// The received tile info object. + /// The tile data. + /// Thrown when any input argument is null. + public TileReceivedEventArgs(TileInfo tileInfo, byte[] tile) + { + if (tileInfo == null) + { + throw new ArgumentNullException(nameof(tileInfo)); + } + if (tile == null) + { + throw new ArgumentNullException(nameof(tile)); + } + + TileInfo = tileInfo; + Tile = tile; + } + + /// + /// Gets the tile information of the received tile. + /// + public TileInfo TileInfo { get; } + + /// + /// Gets the actual tile data. + /// + public byte[] Tile { get; } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile.IO/packages.config =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile.IO/packages.config (revision 0) +++ Core/Components/src/Core.Components.BruTile.IO/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/BruTileReflectionHelper.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/BruTileReflectionHelper.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/BruTileReflectionHelper.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,77 @@ +// 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.Reflection; +using BruTile; +using BruTile.Web; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// Class with helper methods for retrieving data using reflection. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/ReflectionHelper.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + internal static class BruTileReflectionHelper + { + /// + /// Gets the for the given . + /// + /// The tile source. + /// The tile provider. + /// Thrown when + /// is null. + /// Thrown when does + /// not have the expected field to get the from. + /// Thrown when caller does not have permission + /// to access the expected field that holds the instance. + internal static ITileProvider GetProviderFromTileSource(ITileSource source) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + FieldInfo fi = null; + // Note: This implementation respects inheritance. Cannot use 'source.GetType()' + // as that only grant access to fields declared in that type. Therefore the _provider + // field would be inaccessible if 'source' would be an extended type of those below. + if (source is HttpTileSource) + { + fi = typeof(HttpTileSource).GetField("_provider", BindingFlags.Instance | BindingFlags.NonPublic); + } + else if (source is TileSource) + { + fi = typeof(TileSource).GetField("_provider", BindingFlags.Instance | BindingFlags.NonPublic); + } + + if (fi == null) + { + throw new NotSupportedException($"Unable to find a {typeof(ITileProvider).Name} field for type {source.GetType().Name}."); + } + + return (ITileProvider) fi.GetValue(source); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/IConfiguration.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/IConfiguration.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/IConfiguration.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,80 @@ +// 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 BruTile; +using BruTile.Wms; +using Core.Components.BruTile.IO; +using Core.Components.Gis.Exceptions; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// Interface for all classes that can configure a . + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/IConfiguration.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public interface IConfiguration : IDisposable + { + /// + /// Gets the . + /// + ITileSource TileSource { get; } + + /// + /// Gets the . + /// + ITileFetcher TileFetcher { get; } + + /// + /// Gets a value indicating whether the configuration has been fully initialized + /// or not. + /// + /// can be used to initialize the configuration + /// if needed. + bool Initialized { get; } + + /// + /// Gets a deep copy of the configuration. + /// + /// The cloned configuration. + /// Thrown when calling this method while + /// this instance is disposed. + /// Thrown when creating the file + /// cache failed. + IConfiguration Clone(); + + /// + /// Properly initialize the configuration, making it ready for tile fetching. + /// + /// Thrown when the configured + /// cannot be found. + /// Thrown when the configured + /// tile cache cannot be created. + /// Thrown when + /// doesn't allow for tiles to be received. + /// Thrown when calling this method while + /// this instance is disposed. + void Initialize(); + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/ITileSourceFactory.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/ITileSourceFactory.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/ITileSourceFactory.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,45 @@ +// 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.Collections.Generic; +using BruTile; +using BruTile.Wmts; +using Core.Components.Gis.Exceptions; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// Interface for objects responsible for creating from a + /// given URL. + /// + public interface ITileSourceFactory + { + /// + /// Returns all tile sources based on the capabilities of a Web Map Tile Service. + /// + /// The URL to the 'GetCapabilities' part of the service. + /// The tile sources with initialized + /// with an instance of . + /// Thrown when unable to retrieve + /// tile sources from the given service. + IEnumerable GetWmtsTileSources(string capabilitiesUrl); + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/PersistentCacheConfiguration.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/PersistentCacheConfiguration.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/PersistentCacheConfiguration.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,176 @@ +// 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.IO; +using BruTile; +using BruTile.Cache; +using Core.Common.Utils; +using Core.Components.BruTile.Data; +using Core.Components.BruTile.IO; +using Core.Components.BruTile.Properties; +using Core.Components.Gis.Exceptions; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// Base class for a persistent cache configuration. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/CacheConfiguration.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public abstract class PersistentCacheConfiguration : IConfiguration + { + protected readonly string PersistentCacheDirectoryPath; + + /// + /// Initialized a new instance of . + /// + /// The path to the directory for this + /// cache to keep its data. + /// Thrown when + /// is invalid. + protected PersistentCacheConfiguration(string persistentCacheDirectoryPath) + { + if (!IOUtils.IsValidFolderPath(persistentCacheDirectoryPath)) + { + throw new ArgumentException(string.Format((string) Resources.PersistentCacheConfiguration_Invalid_path_for_persistent_cache, + persistentCacheDirectoryPath), + nameof(persistentCacheDirectoryPath)); + } + PersistentCacheDirectoryPath = persistentCacheDirectoryPath; + } + + public ITileSource TileSource { get; private set; } + public ITileFetcher TileFetcher { get; private set; } + public bool Initialized { get; protected set; } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public abstract IConfiguration Clone(); + + public abstract void Initialize(); + + protected virtual void Dispose(bool disposing) + { + if (IsDisposed) + { + return; + } + + if (disposing) + { + TileFetcher?.Dispose(); + } + + IsDisposed = true; + } + + /// + /// Initialized the configuration based on the given . + /// + /// The tile source to initialize for. + /// Thrown when a critical error + /// occurs when creating the tile cache. + /// Thrown when + /// does not allow for tiles to be retrieved. + /// Thrown when calling this method while + /// this instance is disposed. + protected void InitializeFromTileSource(ITileSource tileSource) + { + ThrowExceptionIfDisposed(); + + TileSource = tileSource; + IPersistentCache tileCache = CreateTileCache(); + try + { + ITileProvider provider = BruTileReflectionHelper.GetProviderFromTileSource(tileSource); + TileFetcher = new AsyncTileFetcher(provider, + BruTileSettings.MemoryCacheMinimum, + BruTileSettings.MemoryCacheMaximum, + tileCache); + } + catch (Exception e) when (e is NotSupportedException || e is ArgumentException) + { + throw new CannotReceiveTilesException(Resources.Configuration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provider, e); + } + Initialized = true; + } + + /// + /// Thrown an when + /// is true. + /// + /// Thrown when calling this method while + /// this instance is disposed. + protected void ThrowExceptionIfDisposed() + { + if (IsDisposed) + { + throw new ObjectDisposedException(GetType().Name); + } + } + + /// + /// Creates the tile cache. + /// + /// The file cache. + /// Thrown when a critical error + /// occurs when creating the tile cache. + /// Thrown when calling this method while + /// this instance is disposed. + protected IPersistentCache CreateTileCache() + { + ThrowExceptionIfDisposed(); + + if (!Directory.Exists(PersistentCacheDirectoryPath)) + { + try + { + Directory.CreateDirectory(PersistentCacheDirectoryPath); + } + catch (Exception e) when (SupportedCreateDirectoryExceptions(e)) + { + string message = Resources.PersistentCacheConfiguration_CreateTileCache_Critical_error_while_creating_tile_cache; + throw new CannotCreateTileCacheException(message, e); + } + } + + return new FileCache(PersistentCacheDirectoryPath, BruTileSettings.PersistentCacheFormat, + TimeSpan.FromDays(BruTileSettings.PersistentCacheExpireInDays)); + } + + private bool IsDisposed { get; set; } + + private static bool SupportedCreateDirectoryExceptions(Exception exception) + { + return exception is IOException + || exception is UnauthorizedAccessException + || exception is ArgumentException + || exception is NotSupportedException; + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/TileSourceFactory.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/TileSourceFactory.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/TileSourceFactory.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,95 @@ +// 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 System.Net; +using BruTile; +using BruTile.Wmts; +using Core.Components.BruTile.Properties; +using Core.Components.Gis.Exceptions; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// Class responsible for creating instances for a given + /// source. + /// + public class TileSourceFactory : ITileSourceFactory + { + private static ITileSourceFactory instance; + + /// + /// Gets the singleton instance of . + /// + public static ITileSourceFactory Instance + { + get + { + return instance ?? (instance = new TileSourceFactory()); + } + set + { + instance = value; + } + } + + public IEnumerable GetWmtsTileSources(string capabilitiesUrl) + { + ITileSource[] wmtsTileSources = ParseWmtsTileSources(capabilitiesUrl).ToArray(); + if(wmtsTileSources.Any(ts => !(ts.Schema is WmtsTileSchema))) + { + throw new CannotFindTileSourceException(Resources.TileSourceFactory_GetWmtsTileSources_TileSource_without_WmtsTileSchema_error); + } + return wmtsTileSources; + } + + /// + /// Parses the capabilities XML provided by the WMTS. + /// + /// The WMTS url. + /// The tile sources offered by the service. + /// Thrown when unable to connect + /// to the WMTS and parse the response. + private static IEnumerable ParseWmtsTileSources(string capabilitiesUrl) + { + try + { + WebRequest req = WebRequest.Create(capabilitiesUrl); + using (WebResponse resp = req.GetResponse()) + { + using (Stream s = resp.GetResponseStream()) + { + return WmtsParser.Parse(s); + } + } + } + catch (Exception e) + { + string message = string.Format(Resources.TileSourceFactory_ParseWmtsTileSources_Cannot_connect_to_WMTS_0_, + capabilitiesUrl); + throw new CannotFindTileSourceException(message, e); + } + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,121 @@ +// 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.IO; +using BruTile; +using BruTile.Predefined; +using BruTile.Web; +using Core.Components.BruTile.Data; + +namespace Core.Components.BruTile.Configurations +{ + /// + /// A configuration for a connection to built-in web-based tile services. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/KnownTileLayerConfiguration.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public class WellKnownTileSourceLayerConfiguration : PersistentCacheConfiguration + { + private readonly KnownTileSource knownTileSource; + + /// + /// Creates an instance of . + /// + /// The built-in tile provider to be used. + /// The directory path to the persistent tile cache. + /// Thrown when + /// is an invalid folder path + /// Thrown when + /// isn't a supported member. + /// Thrown when creating the file + /// cache failed. + private WellKnownTileSourceLayerConfiguration(string persistentCacheDirectoryPath, KnownTileSource knownTileSource) + : base(persistentCacheDirectoryPath) + { + this.knownTileSource = knownTileSource; + + HttpTileSource httpTileSource = KnownTileSources.Create(knownTileSource); + InitializeFromTileSource(httpTileSource); + } + + /// + /// Creates a new initialized instance of . + /// + /// The built-in tile provider to be used. + /// The tile source corresponding to . + /// Thrown when creating the file + /// cache failed. + private WellKnownTileSourceLayerConfiguration(KnownTileSource knownTileSource, ITileSource tileSource) + : base(SuggestTileCachePath(tileSource, knownTileSource)) + { + this.knownTileSource = knownTileSource; + + InitializeFromTileSource(tileSource); + } + + /// + /// Creates a fully initialized instance of . + /// + /// The built-in tile provider to be used. + /// The new . + /// Thrown when + /// isn't a supported member. + /// Thrown when creating the file + /// cache failed. + public static WellKnownTileSourceLayerConfiguration CreateInitializedConfiguration(KnownTileSource knownTileSource) + { + HttpTileSource tileSource = KnownTileSources.Create(knownTileSource); + + return new WellKnownTileSourceLayerConfiguration(knownTileSource, tileSource); + } + + public override IConfiguration Clone() + { + ThrowExceptionIfDisposed(); + + return new WellKnownTileSourceLayerConfiguration(PersistentCacheDirectoryPath, knownTileSource); + } + + public override void Initialize() + { + ThrowExceptionIfDisposed(); + + Initialized = true; + } + + private static string SuggestTileCachePath(ITileSource tileSource, KnownTileSource knownTileSource) + { + ITileSchema tileSchema = tileSource.Schema; + string host = knownTileSource.ToString(); + string format = tileSchema.Format; + + foreach (var c in Path.GetInvalidFileNameChars()) + { + host = host.Replace(c, '$'); + } + + return Path.Combine(BruTileSettings.PersistentCacheDirectoryRoot, "WellKnown", host, format); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Configurations/WmtsLayerConfiguration.cs =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/Configurations/WmtsLayerConfiguration.cs (revision 0) +++ Core/Components/src/Core.Components.BruTile/Configurations/WmtsLayerConfiguration.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,228 @@ +// 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 + /// doesn't contain a . + 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). + 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); + } + + public override IConfiguration Clone() + { + ThrowExceptionIfDisposed(); + + return new WmtsLayerConfiguration(capabilitiesUri, capabilityIdentifier, preferredFormat, PersistentCacheDirectoryPath); + } + + public override void Initialize() + { + ThrowExceptionIfDisposed(); + + 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); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/Core.Components.BruTile.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.BruTile/Core.Components.BruTile.csproj (.../Core.Components.BruTile.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/src/Core.Components.BruTile/Core.Components.BruTile.csproj (.../Core.Components.BruTile.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -32,22 +32,86 @@ AllRules.ruleset + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + ..\..\..\..\packages\BruTile.Desktop.0.19.0\lib\net40\BruTile.Desktop.dll + True + + + ..\..\..\..\packages\BruTile.Desktop.0.19.0\lib\net40\BruTile.MbTiles.dll + True + + + ..\..\..\..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net40\System.Data.SQLite.dll + True + Properties\GlobalAssembly.cs + + + + + + + + + True + True + Resources.resx + Copying.Lesser.licenseheader + + + + {F49BD8B2-332A-4C91-A196-8CCE0A2C7D98} + Core.Common.Utils + False + + + {3DCEF8F6-CB6D-435C-9539-50143DACD86C} + Core.Components.BruTile.Data + False + + + {6B280C25-DB18-4F80-86D3-1CBA65208F9D} + Core.Components.BruTile.IO + False + + + {318ba582-88c9-4816-a54a-a7e431461de3} + Core.Components.Gis + False + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bron staat het niet toe om toegang te krijgen tot de kaart tegels. + + + Een kritieke fout is opgetreden bij het aanmaken van de cache. + + + Het pad naar bestandsmap '{0}' is niet geschikt om de kaart tegels in op te slaan. + + + Een databron is niet volgens het WMTS protocol aangeleverd. + + + Niet in staat om de databronnen op te halen bij de WMTS url '{0}'. + + + Niet in staat om de databron met naam '{0}' te kunnen vinden bij de WMTS url '{1}'. + + + Afbeelding formaat moet opgegeven worden als MIME-type. + + + Bron bevat geen WMTS schema. + + \ No newline at end of file Index: Core/Components/src/Core.Components.BruTile/packages.config =================================================================== diff -u --- Core/Components/src/Core.Components.BruTile/packages.config (revision 0) +++ Core/Components/src/Core.Components.BruTile/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial.Forms/Core.Components.DotSpatial.Forms.csproj =================================================================== diff -u -r8ed20afbbecb8d353372e6623e7bbf68cdee543c -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.DotSpatial.Forms/Core.Components.DotSpatial.Forms.csproj (.../Core.Components.DotSpatial.Forms.csproj) (revision 8ed20afbbecb8d353372e6623e7bbf68cdee543c) +++ Core/Components/src/Core.Components.DotSpatial.Forms/Core.Components.DotSpatial.Forms.csproj (.../Core.Components.DotSpatial.Forms.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -80,7 +80,6 @@ UserControl - Component @@ -90,26 +89,7 @@ True Resources.resx - - - - - Form - - - WmtsConnectionDialog.cs - - - - - - - UserControl - - - WmtsLocationControl.cs - @@ -137,6 +117,16 @@ Core.Common.Utils False + + {1BA9EBD0-AA64-4BE3-9791-B2EE344EC938} + Core.Components.BruTile.Forms + False + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + False + {aa47e858-a2a7-470e-8b2d-c76ae8ed9ccd} Core.Components.DotSpatial @@ -162,24 +152,12 @@ - PublicResXFileCodeGenerator + ResXFileCodeGenerator Resources.Designer.cs Designer - - WmtsConnectionDialog.cs - - - WmtsLocationControl.cs - Designer - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\information.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\mapsicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Coördinatenstelsel + + + Formaat + + + Kaartlaag + + + Titel + + + Bewerken + + + WMTS locatie aanpassen + + + URL naar het WMTS dataservice inclusief 'capabilities'. + + + Web Map Tile Service (WMTS) + + \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Resources/information.png =================================================================== diff -u Binary files differ Index: Core/Components/src/Core.Components.Gis.Forms/Resources/mapsicon.png =================================================================== diff -u Binary files differ Index: Core/Components/src/Core.Components.Gis.Forms/Views/IBackgroundMapDataSelectionControl.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/IBackgroundMapDataSelectionControl.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/IBackgroundMapDataSelectionControl.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,53 @@ +// 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.Windows.Forms; +using Core.Components.Gis.Data; + +namespace Core.Components.Gis.Forms.Views +{ + /// + /// Interface for a user control that has a background MapData. + /// + public interface IBackgroundMapDataSelectionControl + { + /// + /// Fired when the has been changed. + /// + event EventHandler SelectedMapDataChanged; + + /// + /// Gets the display name of the user control; + /// + string DisplayName { get; } + + /// + /// Gets the selected or null if none selected. + /// + WmtsMapData SelectedMapData { get; } + + /// + /// Gets the user control. + /// + UserControl UserControl { get; } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsCapabilityRow.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsCapabilityRow.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsCapabilityRow.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,95 @@ +// 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; + +namespace Core.Components.Gis.Forms.Views +{ + /// + /// Class for displaying a as a row in a grid view. + /// + public class WmtsCapabilityRow + { + /// + /// Creates new instance of . + /// + /// The to wrap + /// so that it can be displayed as a row. + /// Thrown when is null. + public WmtsCapabilityRow(WmtsCapability wmtsCapability) + { + if (wmtsCapability == null) + { + throw new ArgumentNullException(nameof(wmtsCapability)); + } + WmtsCapability = wmtsCapability; + } + + /// + /// Gets the id of the . + /// + public string Id + { + get + { + return WmtsCapability.Id; + } + } + + /// + /// Gets the image format of the . + /// + public string Format + { + get + { + return WmtsCapability.Format; + } + } + + /// + /// Gets the title of the . + /// + public string Title + { + get + { + return WmtsCapability.Title; + } + } + + /// + /// Gets the coordinate system of the . + /// + public string CoordinateSystem + { + get + { + return WmtsCapability.CoordinateSystem; + } + } + + /// + /// Gets the this row contains. + /// + public WmtsCapability WmtsCapability { get; } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.Designer.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.Designer.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.Designer.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,146 @@ +// 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. + +namespace Core.Components.Gis.Forms.Views +{ + partial class WmtsConnectionDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WmtsConnectionDialog)); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.nameTextBox = new System.Windows.Forms.TextBox(); + this.urlTextBox = new System.Windows.Forms.TextBox(); + this.nameLabel = new System.Windows.Forms.Label(); + this.urlLabel = new System.Windows.Forms.Label(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.cancelButton = new System.Windows.Forms.Button(); + this.actionButton = new System.Windows.Forms.Button(); + this.urlTooltipErrorProvider = new System.Windows.Forms.ErrorProvider(this.components); + this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); + this.tableLayoutPanel2.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.urlTooltipErrorProvider)).BeginInit(); + this.flowLayoutPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel2 + // + resources.ApplyResources(this.tableLayoutPanel2, "tableLayoutPanel2"); + this.tableLayoutPanel2.Controls.Add(this.nameTextBox, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.urlTextBox, 1, 1); + this.tableLayoutPanel2.Controls.Add(this.nameLabel, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 0, 1); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + // + // nameTextBox + // + resources.ApplyResources(this.nameTextBox, "nameTextBox"); + this.nameTextBox.Name = "nameTextBox"; + // + // urlTextBox + // + resources.ApplyResources(this.urlTextBox, "urlTextBox"); + this.urlTextBox.Name = "urlTextBox"; + // + // nameLabel + // + resources.ApplyResources(this.nameLabel, "nameLabel"); + this.nameLabel.Name = "nameLabel"; + // + // urlLabel + // + resources.ApplyResources(this.urlLabel, "urlLabel"); + this.urlLabel.Name = "urlLabel"; + // + // flowLayoutPanel1 + // + resources.ApplyResources(this.flowLayoutPanel1, "flowLayoutPanel1"); + this.flowLayoutPanel1.Controls.Add(this.cancelButton); + this.flowLayoutPanel1.Controls.Add(this.actionButton); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + // + // cancelButton + // + resources.ApplyResources(this.cancelButton, "cancelButton"); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.UseVisualStyleBackColor = true; + // + // actionButton + // + resources.ApplyResources(this.actionButton, "actionButton"); + this.actionButton.Name = "actionButton"; + this.actionButton.UseVisualStyleBackColor = true; + // + // urlTooltipErrorProvider + // + this.urlTooltipErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink; + this.urlTooltipErrorProvider.ContainerControl = this; + // + // flowLayoutPanel2 + // + resources.ApplyResources(this.flowLayoutPanel2, "flowLayoutPanel2"); + this.flowLayoutPanel2.Controls.Add(this.urlLabel); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + // + // WmtsConnectionDialog + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tableLayoutPanel2); + this.Controls.Add(this.flowLayoutPanel1); + this.Name = "WmtsConnectionDialog"; + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.urlTooltipErrorProvider)).EndInit(); + this.flowLayoutPanel2.ResumeLayout(false); + this.flowLayoutPanel2.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.TextBox urlTextBox; + private System.Windows.Forms.TextBox nameTextBox; + private System.Windows.Forms.Button actionButton; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.Label nameLabel; + private System.Windows.Forms.Label urlLabel; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; + private System.Windows.Forms.ErrorProvider urlTooltipErrorProvider; + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,136 @@ +// 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.Windows.Forms; +using Core.Common.Controls.Dialogs; +using System.Drawing; +using Core.Components.Gis.Forms.Properties; + +namespace Core.Components.Gis.Forms.Views +{ + /// + /// A dialog allowing the user to create an instance of . + /// + public partial class WmtsConnectionDialog : DialogBase + { + /// + /// Creates a new instance of in edit mode. + /// + /// The parent of the dialog. + /// The information to set in the input boxes. + /// Thrown when is null. + public WmtsConnectionDialog(IWin32Window dialogParent, WmtsConnectionInfo wmtsConnectionInfo = null) + : base(dialogParent, Resources.MapsIcon, 400, 150) + { + InitializeComponent(); + + if (wmtsConnectionInfo != null) + { + SetWmtsConnectionInfo(wmtsConnectionInfo); + } + + UpdateActionButton(); + InitializeEventHandlers(); + InitializeErrorProvider(); + } + + /// + /// Gets the name of the WMTS. + /// + public string WmtsConnectionName { get; private set; } + + /// + /// Gets the URL to the GetCapabilities() of the WMTS. + /// + public string WmtsConnectionUrl { get; private set; } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + components?.Dispose(); + } + base.Dispose(disposing); + } + + protected override Button GetCancelButton() + { + return cancelButton; + } + + private void SetWmtsConnectionInfo(WmtsConnectionInfo wmtsConnectionInfo) + { + nameTextBox.Text = wmtsConnectionInfo.Name; + urlTextBox.Text = wmtsConnectionInfo.Url; + actionButton.Text = Resources.WmtsConnectionDialog_ActionButton_Edit; + Text = Resources.WmtsConnectionDialog_Text_Edit; + } + + private void InitializeErrorProvider() + { + urlTooltipErrorProvider.SetError(urlLabel, Resources.WmtsConnectionDialog_UrlErrorProvider_HelpText); + urlTooltipErrorProvider.Icon = GetIcon(Resources.InformationIcon); + + urlTooltipErrorProvider.SetIconAlignment(urlLabel, ErrorIconAlignment.MiddleRight); + } + + private static Icon GetIcon(Bitmap myBitmap) + { + return Icon.FromHandle(myBitmap.GetHicon()); + } + + private void UpdateActionButton() + { + actionButton.Enabled = !(string.IsNullOrWhiteSpace(nameTextBox.Text) || string.IsNullOrWhiteSpace(urlTextBox.Text)); + } + + #region Event handling + + private void InitializeEventHandlers() + { + actionButton.Click += ActionButton_Click; + nameTextBox.TextChanged += NameTextbox_Changed; + urlTextBox.TextChanged += UrlTextbox_Changed; + } + + private void NameTextbox_Changed(object sender, EventArgs e) + { + UpdateActionButton(); + } + + private void UrlTextbox_Changed(object sender, EventArgs e) + { + UpdateActionButton(); + } + + private void ActionButton_Click(object sender, EventArgs e) + { + WmtsConnectionName = nameTextBox.Text; + WmtsConnectionUrl = urlTextBox.Text; + + DialogResult = DialogResult.OK; + Close(); + } + + #endregion + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.resx =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.resx (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsConnectionDialog.resx (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 2 + + + + Top, Left, Right + + + + 82, 3 + + + 6, 3, 6, 3 + + + 50, 4 + + + 326, 20 + + + 1 + + + nameTextBox + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 0 + + + Top, Left, Right + + + 82, 29 + + + 6, 3, 6, 3 + + + 50, 4 + + + 326, 20 + + + 2 + + + urlTextBox + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 1 + + + True + + + 3, 6 + + + 3, 6, 3, 0 + + + 70, 13 + + + 5 + + + Omschrijving: + + + nameLabel + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 2 + + + True + + + True + + + 3, 6 + + + 3, 6, 3, 3 + + + 32, 13 + + + 6 + + + URL: + + + urlLabel + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel2 + + + 0 + + + Fill + + + 3, 29 + + + 0, 0, 0, 6 + + + 70, 28 + + + 7 + + + flowLayoutPanel2 + + + System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 3 + + + Fill + + + 10, 12 + + + 2 + + + 414, 59 + + + 0 + + + tableLayoutPanel2 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="nameTextBox" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="urlTextBox" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="nameLabel" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="flowLayoutPanel2" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Absolute,20" /></TableLayoutSettings> + + + True + + + 336, 3 + + + 75, 23 + + + 4 + + + Annuleren + + + cancelButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel1 + + + 0 + + + 255, 3 + + + 75, 23 + + + 3 + + + Toevoegen + + + actionButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel1 + + + 1 + + + Bottom + + + 10, 71 + + + Yes + + + 414, 29 + + + 2 + + + flowLayoutPanel1 + + + System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + 123, 17 + + + True + + + 6, 13 + + + 434, 112 + + + 10, 12, 10, 12 + + + Nieuwe WMTS locatie toevoegen + + + urlTooltipErrorProvider + + + System.Windows.Forms.ErrorProvider, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + WmtsConnectionDialog + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.Designer.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.Designer.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.Designer.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,140 @@ +// 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. + +namespace Core.Components.Gis.Forms.Views +{ + partial class WmtsLocationControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WmtsLocationControl)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.urlLocationLabel = new System.Windows.Forms.Label(); + this.urlLocationComboBox = new System.Windows.Forms.ComboBox(); + this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); + this.connectToButton = new System.Windows.Forms.Button(); + this.addLocationButton = new System.Windows.Forms.Button(); + this.editLocationButton = new System.Windows.Forms.Button(); + this.dataGridViewControl = new Core.Common.Controls.DataGrid.DataGridViewControl(); + this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + this.flowLayoutPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1"); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.dataGridViewControl, 0, 2); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + // + // tableLayoutPanel2 + // + resources.ApplyResources(this.tableLayoutPanel2, "tableLayoutPanel2"); + this.tableLayoutPanel2.Controls.Add(this.urlLocationLabel, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.urlLocationComboBox, 1, 0); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + // + // urlLocationLabel + // + resources.ApplyResources(this.urlLocationLabel, "urlLocationLabel"); + this.urlLocationLabel.Name = "urlLocationLabel"; + // + // urlLocationComboBox + // + resources.ApplyResources(this.urlLocationComboBox, "urlLocationComboBox"); + this.urlLocationComboBox.FormattingEnabled = true; + this.urlLocationComboBox.Name = "urlLocationComboBox"; + // + // flowLayoutPanel2 + // + resources.ApplyResources(this.flowLayoutPanel2, "flowLayoutPanel2"); + this.flowLayoutPanel2.Controls.Add(this.connectToButton); + this.flowLayoutPanel2.Controls.Add(this.addLocationButton); + this.flowLayoutPanel2.Controls.Add(this.editLocationButton); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + // + // connectToButton + // + resources.ApplyResources(this.connectToButton, "connectToButton"); + this.connectToButton.Name = "connectToButton"; + this.connectToButton.UseVisualStyleBackColor = true; + // + // addButton + // + resources.ApplyResources(this.addLocationButton, "addLocationButton"); + this.addLocationButton.Name = "addLocationButton"; + this.addLocationButton.UseVisualStyleBackColor = true; + // + // editButton + // + resources.ApplyResources(this.editLocationButton, "editLocationButton"); + this.editLocationButton.Name = "editLocationButton"; + this.editLocationButton.UseVisualStyleBackColor = true; + // + // dataGridView + // + this.dataGridViewControl.Dock = System.Windows.Forms.DockStyle.Fill; + resources.ApplyResources(this.dataGridViewControl, "dataGridViewControl"); + this.dataGridViewControl.Name = "dataGridViewControl"; + // + // WmtsLayerControl + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "WmtsLayerControl"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + this.flowLayoutPanel2.ResumeLayout(false); + this.flowLayoutPanel2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private Core.Common.Controls.DataGrid.DataGridViewControl dataGridViewControl; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; + private System.Windows.Forms.Label urlLocationLabel; + private System.Windows.Forms.ComboBox urlLocationComboBox; + private System.Windows.Forms.Button connectToButton; + private System.Windows.Forms.Button addLocationButton; + private System.Windows.Forms.Button editLocationButton; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + } +} Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,400 @@ +// 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 System.Windows.Forms; +using Core.Common.Gui.Settings; +using Core.Common.IO.Exceptions; +using Core.Components.Gis.Data; +using Core.Components.Gis.Exceptions; +using Core.Components.Gis.Forms.Properties; +using Core.Components.Gis.IO.Readers; +using Core.Components.Gis.IO.Writers; +using log4net; +using BaseResources = Core.Common.Base.Properties.Resources; + +namespace Core.Components.Gis.Forms.Views +{ + /// + /// This class represents a where a WMTS layer can be selected. + /// + public partial class WmtsLocationControl : UserControl, IBackgroundMapDataSelectionControl + { + private readonly IWmtsCapabilityFactory wmtsCapabilityFactory; + private const string wmtsConnectionInfoFileName = "wmtsConnectionInfo.config"; + private static readonly ILog log = LogManager.GetLogger(typeof(WmtsLocationControl)); + private readonly List wmtsConnectionInfos; + + private readonly List capabilities; + private string wmtsConnectionInfoFilePath; + + /// + /// Creates a new instance of . + /// + /// The active or null if none active. + /// The to use. + /// Thrown when is null. + public WmtsLocationControl(WmtsMapData activeWmtsMapData, IWmtsCapabilityFactory wmtsCapabilityFactory) + { + if (wmtsCapabilityFactory == null) + { + throw new ArgumentNullException(nameof(wmtsCapabilityFactory)); + } + + this.wmtsCapabilityFactory = wmtsCapabilityFactory; + + wmtsConnectionInfos = new List(); + capabilities = new List(); + + InitializeComponent(); + InitializeWmtsConnectionInfos(); + InitializeDataGridView(); + InitializeComboBoxDataSource(); + InitializeEventHandlers(); + + SetActiveWmtsMapData(activeWmtsMapData); + + UpdateButtons(); + } + + public string DisplayName + { + get + { + return Resources.WmtsLocationControl_DisplayName; + } + } + + public WmtsMapData SelectedMapData + { + get + { + WmtsCapabilityRow currentRow = GetSelectedWmtsCapabilityRow(); + if (currentRow == null) + { + return null; + } + + WmtsConnectionInfo selectedWmtsConnectionInfo = GetSelectedWmtsConnectionInfo(); + if (selectedWmtsConnectionInfo == null) + { + return null; + } + + return currentRow.WmtsCapability.ToWmtsMapdata(selectedWmtsConnectionInfo.Name, selectedWmtsConnectionInfo.Url); + } + } + + public UserControl UserControl + { + get + { + return this; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + components?.Dispose(); + } + base.Dispose(disposing); + } + + private void SetActiveWmtsMapData(WmtsMapData activeWmtsMapData) + { + WmtsConnectionInfo suggestedInfo = TryCreateWmtsConnectionInfo(activeWmtsMapData?.Name, + activeWmtsMapData?.SourceCapabilitiesUrl); + if (activeWmtsMapData == null || suggestedInfo == null) + { + return; + } + + if (!wmtsConnectionInfos.Any(wi => wi.Equals(suggestedInfo))) + { + wmtsConnectionInfos.Add(suggestedInfo); + } + + UpdateComboBoxDataSource(suggestedInfo); + + DataGridViewRow dataGridViewRow = dataGridViewControl.Rows.OfType() + .FirstOrDefault(row => IsMatch( + (WmtsCapabilityRow) row.DataBoundItem, + activeWmtsMapData)); + if (dataGridViewRow == null) + { + return; + } + DataGridViewCell cell = dataGridViewControl.GetCell(dataGridViewRow.Index, 0); + dataGridViewControl.SetCurrentCell(cell); + } + + private static bool IsMatch(WmtsCapabilityRow wmtsCapabilityRow, WmtsMapData wmtsMapData) + { + return string.Equals(wmtsCapabilityRow.Id, wmtsMapData.SelectedCapabilityIdentifier) + && string.Equals(wmtsCapabilityRow.Format, wmtsMapData.PreferredFormat); + } + + private void InitializeWmtsConnectionInfos() + { + string folderPath = SettingsHelper.Instance.GetApplicationLocalUserSettingsDirectory(SettingsHelper.Instance.ApplicationVersion); + + wmtsConnectionInfoFilePath = Path.Combine(folderPath, wmtsConnectionInfoFileName); + wmtsConnectionInfos.AddRange(TryGetSavedWmtsConnectionInfos()); + } + + private IEnumerable TryGetSavedWmtsConnectionInfos() + { + try + { + var reader = new WmtsConnectionInfoReader(); + return reader.ReadWmtsConnectionInfos(wmtsConnectionInfoFilePath); + } + catch (CriticalFileReadException exception) + { + log.Error(exception.Message, exception); + } + return Enumerable.Empty(); + } + + private void TrySaveWmtsConnectionInfos() + { + try + { + var writer = new WmtsConnectionInfoWriter(wmtsConnectionInfoFilePath); + writer.WriteWmtsConnectionInfo(wmtsConnectionInfos); + } + catch (CriticalFileWriteException exception) + { + log.Error(exception.Message, exception); + } + } + + private static WmtsConnectionInfo TryCreateWmtsConnectionInfo(string wmtsConnectionName, string wmtsConnectionUrl) + { + try + { + return new WmtsConnectionInfo(wmtsConnectionName, wmtsConnectionUrl); + } + catch (ArgumentException) + { + return null; + } + } + + private void UpdateButtons() + { + connectToButton.Enabled = urlLocationComboBox.SelectedItem != null; + editLocationButton.Enabled = urlLocationComboBox.SelectedItem != null; + } + + #region DataGridView + + private void InitializeDataGridView() + { + dataGridViewControl.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridViewControl.MultiSelect = false; + + dataGridViewControl.AddTextBoxColumn(nameof(WmtsCapabilityRow.Id), Resources.WmtsCapability_MapLayer_Id, + true); + dataGridViewControl.AddTextBoxColumn(nameof(WmtsCapabilityRow.Format), Resources.WmtsCapability_MapLayer_Format, + true); + dataGridViewControl.AddTextBoxColumn(nameof(WmtsCapabilityRow.Title), Resources.WmtsCapability_MapLayer_Title, + true); + dataGridViewControl.AddTextBoxColumn(nameof(WmtsCapabilityRow.CoordinateSystem), Resources.WmtsCapability_MapLayer_CoordinateSystem, + true); + } + + private void DataGridViewCurrentCellChangedHandler(object sender, EventArgs e) + { + SelectedMapDataChanged?.Invoke(this, e); + } + + private void UpdateDataGridViewDataSource(IEnumerable wmtsCapabilities) + { + capabilities.Clear(); + foreach (WmtsCapability wmtsCapability in wmtsCapabilities) + { + capabilities.Add(new WmtsCapabilityRow(wmtsCapability)); + } + + UpdateDataGridViewDataSource(); + } + + private void UpdateDataGridViewDataSource() + { + dataGridViewControl.SetDataSource(capabilities.ToArray()); + dataGridViewControl.ClearCurrentCell(); + } + + private WmtsCapabilityRow GetSelectedWmtsCapabilityRow() + { + return dataGridViewControl.CurrentRow?.DataBoundItem as WmtsCapabilityRow; + } + + private void ClearDataGridViewDataSource() + { + capabilities.Clear(); + UpdateDataGridViewDataSource(); + } + + #endregion + + #region ComboBox + + private void InitializeComboBoxDataSource() + { + urlLocationComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + urlLocationComboBox.Sorted = true; + UpdateComboBoxDataSource(); + } + + private void UpdateComboBoxDataSource() + { + UpdateComboBoxDataSource(urlLocationComboBox.SelectedItem); + } + + private void UpdateComboBoxDataSource(object selectedItem) + { + urlLocationComboBox.DataSource = null; + urlLocationComboBox.DataSource = wmtsConnectionInfos; + urlLocationComboBox.DisplayMember = nameof(WmtsConnectionInfo.Name); + urlLocationComboBox.ValueMember = nameof(WmtsConnectionInfo.Url); + + if (selectedItem != null) + { + urlLocationComboBox.SelectedItem = selectedItem; + } + + UpdateButtons(); + } + + private WmtsConnectionInfo GetSelectedWmtsConnectionInfo() + { + return urlLocationComboBox.SelectedItem as WmtsConnectionInfo; + } + + #endregion + + #region Event handlers + + private void InitializeEventHandlers() + { + dataGridViewControl.AddCurrentCellChangedHandler(DataGridViewCurrentCellChangedHandler); + + urlLocationComboBox.SelectedIndexChanged += OnUrlLocationSelectedIndexChanged; + + connectToButton.Click += OnConnectToButtonClick; + addLocationButton.Click += OnAddLocationButtonClick; + editLocationButton.Click += OnEditLocationButtonClick; + } + + private void OnUrlLocationSelectedIndexChanged(object sender, EventArgs e) + { + ClearDataGridViewDataSource(); + + var selectedWmtsConnectionInfo = urlLocationComboBox.SelectedItem as WmtsConnectionInfo; + ConnectToUrl(selectedWmtsConnectionInfo); + } + + private void OnConnectToButtonClick(object sender, EventArgs e) + { + var selectedWmtsConnectionInfo = urlLocationComboBox.SelectedItem as WmtsConnectionInfo; + ConnectToUrl(selectedWmtsConnectionInfo); + } + + private void ConnectToUrl(WmtsConnectionInfo selectedWmtsConnectionInfo) + { + if (selectedWmtsConnectionInfo == null) + { + return; + } + try + { + IEnumerable wmtsCapabilities = wmtsCapabilityFactory.GetWmtsCapabilities(selectedWmtsConnectionInfo.Url).ToArray(); + UpdateDataGridViewDataSource(wmtsCapabilities); + } + catch (CannotFindTileSourceException exception) + { + Form controlForm = FindForm(); + MessageBox.Show(controlForm, exception.Message, BaseResources.Error, MessageBoxButtons.OK, + MessageBoxIcon.Error); + log.Error(exception.Message, exception); + } + } + + private void OnAddLocationButtonClick(object sender, EventArgs eventArgs) + { + Form controlForm = FindForm(); + using (var dialog = new WmtsConnectionDialog(controlForm)) + { + if (dialog.ShowDialog() != DialogResult.OK) + { + return; + } + + WmtsConnectionInfo createdWmtsConnectionInfos = TryCreateWmtsConnectionInfo(dialog.WmtsConnectionName, + dialog.WmtsConnectionUrl); + if (createdWmtsConnectionInfos != null) + { + wmtsConnectionInfos.Add(createdWmtsConnectionInfos); + TrySaveWmtsConnectionInfos(); + UpdateComboBoxDataSource(createdWmtsConnectionInfos); + } + } + } + + private void OnEditLocationButtonClick(object sender, EventArgs eventArgs) + { + var selectedWmtsConnectionInfo = urlLocationComboBox.SelectedItem as WmtsConnectionInfo; + if (selectedWmtsConnectionInfo == null) + { + return; + } + Form controlForm = FindForm(); + using (var dialog = new WmtsConnectionDialog(controlForm, selectedWmtsConnectionInfo)) + { + if (dialog.ShowDialog() != DialogResult.OK) + { + return; + } + + WmtsConnectionInfo createdWmtsConnectionInfos = TryCreateWmtsConnectionInfo(dialog.WmtsConnectionName, + dialog.WmtsConnectionUrl); + if (createdWmtsConnectionInfos != null) + { + wmtsConnectionInfos.Remove(selectedWmtsConnectionInfo); + wmtsConnectionInfos.Add(createdWmtsConnectionInfos); + TrySaveWmtsConnectionInfos(); + UpdateComboBoxDataSource(createdWmtsConnectionInfos); + } + } + } + + public event EventHandler SelectedMapDataChanged; + + #endregion + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.resx =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.resx (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/Views/WmtsLocationControl.resx (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 1 + + + True + + + 2 + + + True + + + + 3, 6 + + + + 3, 6, 3, 0 + + + 73, 13 + + + 0 + + + Locatie (URL) + + + urlLocationLabel + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 0 + + + Fill + + + 82, 3 + + + 396, 21 + + + 1 + + + urlLocationComboBox + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 1 + + + Fill + + + 3, 3 + + + 1 + + + 481, 27 + + + 2 + + + tableLayoutPanel2 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="urlLocationLabel" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="urlLocationComboBox" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="Percent,100" /></TableLayoutSettings> + + + True + + + True + + + 3, 3 + + + 102, 23 + + + 0 + + + Verbinding maken + + + connectToButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel2 + + + 0 + + + True + + + 111, 3 + + + 115, 23 + + + 1 + + + Locatie toevoegen... + + + addLocationButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel2 + + + 1 + + + True + + + 232, 3 + + + 116, 23 + + + 2 + + + Locatie aanpassen... + + + editLocationButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + flowLayoutPanel2 + + + 2 + + + 3, 36 + + + 351, 29 + + + 2 + + + flowLayoutPanel2 + + + System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 1 + + + Fill + + + 3, 71 + + + 481, 146 + + + 0 + + + dataGridViewControl + + + System.Windows.Forms.DataGridView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 2 + + + Fill + + + 0, 0 + + + 3 + + + 487, 220 + + + 0 + + + tableLayoutPanel1 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="flowLayoutPanel2" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="dataGridView" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20" /></TableLayoutSettings> + + + True + + + 6, 13 + + + 487, 220 + + + WmtsLayerControl + + + System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/WmtsCapability.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/WmtsCapability.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/WmtsCapability.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,103 @@ +// 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 Core.Components.Gis.Data; + +namespace Core.Components.Gis.Forms +{ + /// + /// Class representing a capability coming from a Web Map Tile Service (WMTS). + /// + public class WmtsCapability + { + /// + /// Creates a new instance of . + /// + /// The id of the WMTS capability. + /// The type of image format of the WMTS capability. + /// The title of the WMTS capability. + /// The coordinate system of the WMTS capability. + /// Thrown when any of the input parameters is null. + /// Thrown when is not stated as a MIME-type. + public WmtsCapability(string id, string format, string title, string coordinateSystem) + { + if (id == null) + { + throw new ArgumentNullException(nameof(id)); + } + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + if (title == null) + { + throw new ArgumentNullException(nameof(title)); + } + if (coordinateSystem == null) + { + throw new ArgumentNullException(nameof(coordinateSystem)); + } + if (!format.StartsWith("image/")) + { + throw new ArgumentException(@"Specified image format is not a MIME type.", nameof(format)); + } + + Id = id; + Format = format; + Title = title; + CoordinateSystem = coordinateSystem; + } + + /// + /// Gets the id of the WMTS capability. + /// + public string Id { get;} + + /// + /// Gets the image format of the WMTS capability. + /// + public string Format { get; } + + /// + /// Gets the title of the WMTS capability. + /// + public string Title { get; } + + /// + /// Gets the coordinate system of the WMTS capability. + /// + public string CoordinateSystem { get; } + + /// + /// Creates a new instance of based upon the local properties. + /// + /// The name of the source (for visualization purposes only). + /// The URL to the capabilities of the WMTS. + /// The newly created . + /// Thrown when + /// or is null. + public WmtsMapData ToWmtsMapdata(string displayName, string sourceCapabilitiesUrl) + { + return new WmtsMapData(displayName, sourceCapabilitiesUrl, Id, Format); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.Forms/packages.config =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.Forms/packages.config (revision 0) +++ Core/Components/src/Core.Components.Gis.Forms/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.IO/Core.Components.Gis.IO.csproj =================================================================== diff -u -r23d1e296e2da4364fbfe346e68d582dfcf966bb0 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.Gis.IO/Core.Components.Gis.IO.csproj (.../Core.Components.Gis.IO.csproj) (revision 23d1e296e2da4364fbfe346e68d582dfcf966bb0) +++ Core/Components/src/Core.Components.Gis.IO/Core.Components.Gis.IO.csproj (.../Core.Components.Gis.IO.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -50,6 +50,7 @@ + @@ -66,9 +67,12 @@ + + + Index: Core/Components/src/Core.Components.Gis.IO/Properties/Resources.Designer.cs =================================================================== diff -u -ra666c7d6aa029937de402e181f119c72707bfb73 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.Gis.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision a666c7d6aa029937de402e181f119c72707bfb73) +++ Core/Components/src/Core.Components.Gis.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -211,5 +211,14 @@ return ResourceManager.GetString("ShapeFileWriterBase_CopyToFeature_Mapdata_can_only_contain_one_feature", resourceCulture); } } + + /// + /// Looks up a localized string similar to Het is niet mogelijk om WMTS connectie '{0}' aan te maken met URL '{1}'.. + /// + internal static string WmtsConnectionInfoReader_Unable_To_Create_WmtsConnectionInfo { + get { + return ResourceManager.GetString("WmtsConnectionInfoReader_Unable_To_Create_WmtsConnectionInfo", resourceCulture); + } + } } } Index: Core/Components/src/Core.Components.Gis.IO/Properties/Resources.resx =================================================================== diff -u -ra666c7d6aa029937de402e181f119c72707bfb73 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.Gis.IO/Properties/Resources.resx (.../Resources.resx) (revision a666c7d6aa029937de402e181f119c72707bfb73) +++ Core/Components/src/Core.Components.Gis.IO/Properties/Resources.resx (.../Resources.resx) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -160,4 +160,7 @@ Kaartlaag toevoegen afgebroken. Geen data ingelezen. + + Het is niet mogelijk om WMTS connectie '{0}' aan te maken met URL '{1}'. + \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.IO/Readers/WmtsConnectionInfoReader.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.IO/Readers/WmtsConnectionInfoReader.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.IO/Readers/WmtsConnectionInfoReader.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,160 @@ +// 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.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; +using Core.Common.IO.Exceptions; +using Core.Common.Utils; +using Core.Common.Utils.Builders; +using Core.Components.Gis.IO.Properties; +using log4net; +using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; + +namespace Core.Components.Gis.IO.Readers +{ + /// + /// Reader class for . + /// + public class WmtsConnectionInfoReader + { + private static readonly ILog log = LogManager.GetLogger(typeof(WmtsConnectionInfoReader)); + private string filePath; + + /// + /// Reads the WMTS Connection info objects from . + /// + /// The file path that contains the information. + /// The read information. + /// Thrown when is invalid. + /// Thrown when could not successfully be read. + /// A valid path: + /// + /// is not empty or null, + /// does not consist out of only whitespace characters, + /// does not contain an invalid character, + /// does not end with a directory or path separator (empty file name). + /// + public ReadOnlyCollection ReadWmtsConnectionInfos(string path) + { + filePath = path; + IOUtils.ValidateFilePath(filePath); + + var readConnectionInfos = new WmtsConnectionInfo[0]; + if (!File.Exists(filePath)) + { + return new ReadOnlyCollection(readConnectionInfos); + } + + try + { + readConnectionInfos = ReadWmtsConnectionInfos().ToArray(); + } + catch (Exception exception) when (exception is XmlException || exception is IOException) + { + string message = new FileReaderErrorMessageBuilder(filePath) + .Build(CoreCommonUtilsResources.Error_General_IO_Import_ErrorMessage); + throw new CriticalFileReadException(message, exception); + } + return new ReadOnlyCollection(readConnectionInfos); + } + + /// + /// Reads the collection of from . + /// + /// The read collection. + /// Thrown when an error occurred while parsing the XML. + private IEnumerable ReadWmtsConnectionInfos() + { + var connectionInfos = new List(); + using (XmlReader reader = XmlReader.Create(filePath)) + { + while (reader.Read()) + { + if (IsReadElementWmtsConnectionElement(reader)) { continue;} + + WmtsConnectionInfo readWmtsConnectionElement = ReadWmtsConnectionElement(reader); + if (readWmtsConnectionElement != null) + { + connectionInfos.Add(readWmtsConnectionElement); + } + } + } + return connectionInfos; + } + + /// + /// Validates if the reader points to the element. + /// + /// The reader to use. + /// true if the reader points to the WMTS connection element, false otherwise. + /// Thrown when the input stream encountered incorrect XML. + private static bool IsReadElementWmtsConnectionElement(XmlReader reader) + { + return reader.NodeType != XmlNodeType.Element + || !reader.IsStartElement() + || reader.Name != WmtsConnectionInfoXmlDefinitions.WmtsConnectionElement; + } + + private WmtsConnectionInfo ReadWmtsConnectionElement(XmlReader reader) + { + using (XmlReader subtreeReader = reader.ReadSubtree()) + { + XElement wmtsConnectionElement = XElement.Load(subtreeReader); + + return TryCreateWmtsConnectionInfo(wmtsConnectionElement); + } + } + + private WmtsConnectionInfo TryCreateWmtsConnectionInfo(XContainer element) + { + XElement nameElement = element.Element(WmtsConnectionInfoXmlDefinitions.WmtsConnectionNameElement); + XElement urlElement = element.Element(WmtsConnectionInfoXmlDefinitions.WmtsConnectionUrlElement); + + if (nameElement == null || urlElement == null) + { + return null; + } + + return TryCreateWmtsConnectionInfo(nameElement.Value, urlElement.Value); + } + + private WmtsConnectionInfo TryCreateWmtsConnectionInfo(string name, string url) + { + try + { + return new WmtsConnectionInfo(name, url); + } + catch (ArgumentException exception) + { + string errorMessage = string.Format(Resources.WmtsConnectionInfoReader_Unable_To_Create_WmtsConnectionInfo, name, url); + string message = new FileReaderErrorMessageBuilder(filePath).Build(errorMessage); + + log.Warn(message, exception); + } + return null; + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.IO/WmtsConnectionInfoXmlDefinitions.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.IO/WmtsConnectionInfoXmlDefinitions.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.IO/WmtsConnectionInfoXmlDefinitions.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,49 @@ +// 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. + +namespace Core.Components.Gis.IO +{ + /// + /// Defines the element names of the WMTS connection configuration file. + /// + public static class WmtsConnectionInfoXmlDefinitions + { + /// + /// Gets the name of the root element. + /// + public const string RootElement = "WmtsConnections"; + + /// + /// Gets the WMTS connection element. + /// + public const string WmtsConnectionElement = "WmtsConnection"; + + /// + /// Gets the WMTS connection name element. + /// + public const string WmtsConnectionNameElement = "Name"; + + /// + /// Gets the WMTS connection URL element. + /// + public const string WmtsConnectionUrlElement = "URL"; + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis.IO/Writers/WmtsConnectionInfoWriter.cs =================================================================== diff -u --- Core/Components/src/Core.Components.Gis.IO/Writers/WmtsConnectionInfoWriter.cs (revision 0) +++ Core/Components/src/Core.Components.Gis.IO/Writers/WmtsConnectionInfoWriter.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,125 @@ +// 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.Xml; +using Core.Common.IO.Exceptions; +using Core.Common.Utils; +using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; + +namespace Core.Components.Gis.IO.Writers +{ + /// + /// Writer class for . + /// + public class WmtsConnectionInfoWriter + { + private readonly string filePath; + + /// + /// Creates a new instance of . + /// + /// Path to write to. + /// Thrown when is invalid. + /// A valid path: + /// + /// is not empty or null, + /// does not consist out of only whitespace characters, + /// does not contain an invalid character, + /// does not end with a directory or path separator (empty file name). + /// + public WmtsConnectionInfoWriter(string filePath) + { + IOUtils.ValidateFilePath(filePath); + this.filePath = filePath; + } + + /// + /// Writes the to . + /// + /// The objects to write. + /// Thrown when is null. + /// Thrown when writing + /// to failed. + public void WriteWmtsConnectionInfo(IEnumerable wmtsConnectionInfos) + { + if (wmtsConnectionInfos == null) + { + throw new ArgumentNullException(nameof(wmtsConnectionInfos)); + } + try + { + WriteWmtsConnectionInfosToXml(wmtsConnectionInfos); + } + catch (SystemException exception) + { + throw new CriticalFileWriteException(string.Format(CoreCommonUtilsResources.Error_General_output_error_0, filePath), exception); + } + } + + private void WriteWmtsConnectionInfosToXml(IEnumerable wmtsConnectionInfos) + { + EnsureParentDirectoryExists(); + using (XmlWriter writer = XmlWriter.Create(filePath)) + { + writer.WriteStartDocument(); + writer.WriteStartElement(WmtsConnectionInfoXmlDefinitions.RootElement); + + foreach (WmtsConnectionInfo wmtsConnectionInfo in wmtsConnectionInfos) + { + WriteWmtsConnectionInfoToXml(writer, wmtsConnectionInfo); + } + + writer.WriteEndElement(); + writer.WriteEndDocument(); + + writer.Flush(); + writer.Close(); + } + } + + /// + /// Creates the parent folder of if it does not exist. + /// + /// Thrown when the network name is not known. + /// Thrown when the caller does not have the + /// required permission. + /// Thrown when the specified path, file name, or + /// both exceed the system-defined maximum length. + /// Thrown when the specified path is invalid. + private void EnsureParentDirectoryExists() + { + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + } + + private static void WriteWmtsConnectionInfoToXml(XmlWriter writer, WmtsConnectionInfo wmtsConnectionInfo) + { + writer.WriteStartElement(WmtsConnectionInfoXmlDefinitions.WmtsConnectionElement); + + writer.WriteElementString(WmtsConnectionInfoXmlDefinitions.WmtsConnectionNameElement, wmtsConnectionInfo.Name); + writer.WriteElementString(WmtsConnectionInfoXmlDefinitions.WmtsConnectionUrlElement, wmtsConnectionInfo.Url); + + writer.WriteEndElement(); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.Gis/Core.Components.Gis.csproj =================================================================== diff -u -r31012b85637f7fcf6b28f498fc996edcda2eb505 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/src/Core.Components.Gis/Core.Components.Gis.csproj (.../Core.Components.Gis.csproj) (revision 31012b85637f7fcf6b28f498fc996edcda2eb505) +++ Core/Components/src/Core.Components.Gis/Core.Components.Gis.csproj (.../Core.Components.Gis.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -52,6 +52,9 @@ + + + True @@ -64,6 +67,7 @@ + @@ -89,6 +93,9 @@ Designer + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.Data.Test/Properties/AssemblyInfo.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.Data.Test/Properties/AssemblyInfo.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.Data.Test/Properties/AssemblyInfo.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ +// 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Core.Components.BruTile.Data.Test")] +[assembly: AssemblyProduct("Core.Components.BruTile.Data.Test")] +[assembly: Guid("18dc8b68-59fb-4246-a9b0-2321d4627e10")] \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.Forms.Test/BruTileWmtsCapabilityFactoryTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.Forms.Test/BruTileWmtsCapabilityFactoryTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.Forms.Test/BruTileWmtsCapabilityFactoryTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,83 @@ +// 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.Linq; +using Core.Components.BruTile.TestUtil; +using Core.Components.Gis.Data; +using Core.Components.Gis.Exceptions; +using Core.Components.Gis.Forms; +using NUnit.Framework; + +namespace Core.Components.BruTile.Forms.Test +{ + [TestFixture] + public class BruTileWmtsCapabilityFactoryTest + { + [Test] + public void Constructor_ExpectedValues() + { + // Call + var factory = new BruTileWmtsCapabilityFactory(); + + // Assert + Assert.IsInstanceOf(factory); + } + + [Test] + [TestCase("")] + [TestCase(null)] + public void GetWmtsCapabilities_CapabilitiesUrlInvalid_ThrowsCannotFindTileSourceException(string url) + { + // Setup + var factory = new BruTileWmtsCapabilityFactory(); + + // Call + TestDelegate call = () => factory.GetWmtsCapabilities(url).ToArray(); + + // Assert + CannotFindTileSourceException exception = Assert.Throws(call); + Assert.AreEqual($"Niet in staat om de databronnen op te halen bij de WMTS url '{url}'.", exception.Message); + } + + [Test] + public void GetWmtsCapabilities_ValidUrl_ReturnsWmtsCapabilities() + { + // Setup + string url = "validUrl"; + var factory = new BruTileWmtsCapabilityFactory(); + WmtsMapData backgroundMapData = WmtsMapData.CreateDefaultPdokMapData(); + + using (new UseCustomTileSourceFactoryConfig(backgroundMapData)) + { + // Call + WmtsCapability[] capabilities = factory.GetWmtsCapabilities(url).ToArray(); + + // Assert + Assert.AreEqual(1, capabilities.Length); + WmtsCapability capability = capabilities[0]; + Assert.AreEqual("brtachtergrondkaart(EPSG:28992)", capability.Id); + Assert.AreEqual("Stub schema", capability.Title); + Assert.AreEqual("image/png", capability.Format); + Assert.AreEqual("EPSG:28992", capability.CoordinateSystem); + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.Forms.Test/Core.Components.BruTile.Forms.Test.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.BruTile.Forms.Test/Core.Components.BruTile.Forms.Test.csproj (.../Core.Components.BruTile.Forms.Test.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/test/Core.Components.BruTile.Forms.Test/Core.Components.BruTile.Forms.Test.csproj (.../Core.Components.BruTile.Forms.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -39,6 +39,10 @@ MinimumRecommendedRules.ruleset + + ..\..\..\..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll + True + @@ -47,12 +51,40 @@ Properties\GlobalAssembly.cs + Copying.Lesser.licenseheader + + + + {3bbfd65b-b277-4e50-ae6d-bd24c3434609} + Core.Common.Base + + + {1BA9EBD0-AA64-4BE3-9791-B2EE344EC938} + Core.Components.BruTile.Forms + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + + + {4A06DF0D-5D75-4BAD-A95A-A3DB9B7C4AD5} + Core.Components.Gis.Forms + + + {318BA582-88C9-4816-A54A-A7E431461DE3} + Core.Components.Gis + + + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Core.Components.BruTile.TestUtil + + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.IO.Test/AsyncTileFetcherTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.IO.Test/AsyncTileFetcherTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.IO.Test/AsyncTileFetcherTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,578 @@ +// 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.Threading; +using BruTile; +using BruTile.Cache; +using Core.Common.TestUtil; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Components.BruTile.IO.Test +{ + [TestFixture] + public class AsyncTileFetcherTest + { + /// + /// Gets the number of ms that is considered an acceptable time to take for fetching + /// a single tile asynchronously in this test-fixture. + /// + private const int allowedTileFetchTime = 100; + + [Test] + public void Constructor_ValidArguments_ExpectedValues() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + // Call + using (var tileFetcher = new AsyncTileFetcher(tileProvider, 100, 200)) + { + // Assert + Assert.IsInstanceOf(tileFetcher); + } + mocks.VerifyAll(); + } + + [Test] + public void Constructor_TileProviderNull_ThrowArgumentNullException() + { + // Call + TestDelegate call = () => new AsyncTileFetcher(null, 100, 200); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("provider", paramName); + } + + [Test] + [TestCase(-1, 0)] + [TestCase(0, -1)] + public void Constructor_NegativeNumberOfTilesForMemoryCacheSettings_ThrowArgumentException(int min, int max) + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + // Call + TestDelegate call = () => new AsyncTileFetcher(tileProvider, min, max); + + // Assert + string message = "Het aantal kaart tegels voor de geheugen cache moeten positief zijn."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; + Assert.AreEqual(min < 0 ? "minTiles" : "maxTiles", paramName); + mocks.VerifyAll(); + } + + [Test] + [TestCase(0, 0)] + [TestCase(200, 100)] + public void Constructor_InvalidInMemoryCacheSettings_ThrowArgumentException(int min, int max) + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + // Call + TestDelegate call = () => new AsyncTileFetcher(tileProvider, min, max); + + // Assert + string message = "Het minimale aantal kaart tegels voor de geheugen cache moet kleiner zijn dan het maximale aantal kaart tegels."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message); + mocks.VerifyAll(); + } + + [Test] + public void GetTile_TileNotCachedAnywhere_GetTileAsynchronouslyFromTileProvider() + { + // Setup + var info = new TileInfo(); + var data = new byte[0]; + + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + tileProvider.Stub(tp => tp.GetTile(info)).Return(data); + + var persistentCache = mocks.Stub>(); + persistentCache.Stub(c => c.Find(info.Index)).Return(null); + persistentCache.Expect(c => c.Add(info.Index, data)); + mocks.ReplayAll(); + + using (var fetcherIsDoneEvent = new AutoResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) + { + TileReceivedEventArgs receivedArguments = null; + int tileReceivedCounter = 0; + fetcher.TileReceived += (sender, args) => + { + receivedArguments = args; + tileReceivedCounter++; + }; + + int queueEmptyCounter = 0; + fetcher.QueueEmpty += (sender, args) => + { + queueEmptyCounter++; + fetcherIsDoneEvent.Set(); + }; + + // Call + byte[] fetchedData = fetcher.GetTile(info); + + // Assert + Assert.IsNull(fetchedData, + "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + + if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) + { + Assert.AreEqual(1, tileReceivedCounter); + Assert.AreSame(data, receivedArguments.Tile); + Assert.AreSame(info, receivedArguments.TileInfo); + + Assert.AreEqual(1, queueEmptyCounter); + } + else + { + Assert.Fail("TileFetcher did not respond within timelimit."); + } + } + mocks.VerifyAll(); + } + + [Test] + public void GetTile_TileAlreadyFetched_GetTileFromMemoryCache() + { + // Setup + var info = new TileInfo(); + var data = new byte[0]; + + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + tileProvider.Stub(tp => tp.GetTile(info)).Return(data); + + var persistentCache = mocks.Stub>(); + persistentCache.Stub(c => c.Find(info.Index)).Return(null); + persistentCache.Stub(c => c.Add(info.Index, data)); + mocks.ReplayAll(); + + using (var fetcherFiredAsyncEvent = new AutoResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) + { + fetcher.QueueEmpty += (sender, args) => { fetcherFiredAsyncEvent.Set(); }; + + byte[] fetchedData = fetcher.GetTile(info); + + // Precondition + Assert.IsNull(fetchedData, + "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + if (!fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) + { + Assert.Fail("TileFetcher did not respond within timelimit."); + } + fetcherFiredAsyncEvent.Reset(); + + // Assert + fetchedData = fetcher.GetTile(info); + Assert.AreSame(data, fetchedData); + + if (fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) + { + Assert.Fail("TileFetcher should not fire asynchronous events if tile is retrieved from cache."); + } + + mocks.VerifyAll(); + } + } + + [Test] + public void GetTile_TileAlreadyInPersistentCache_GetTileFromPersistentCache() + { + // Setup + var info = new TileInfo(); + var data = new byte[0]; + + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + tileProvider.Stub(tp => tp.GetTile(info)).Return(data); + + var persistentCache = mocks.Stub>(); + persistentCache.Stub(c => c.Find(info.Index)).Return(data); + mocks.ReplayAll(); + + using (var fetcherFiredAsyncEvent = new AutoResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) + { + fetcher.TileReceived += (sender, args) => { fetcherFiredAsyncEvent.Set(); }; + fetcher.QueueEmpty += (sender, args) => { fetcherFiredAsyncEvent.Set(); }; + + byte[] fetchedData = fetcher.GetTile(info); + + // Assert + Assert.AreSame(data, fetchedData); + + if (fetcherFiredAsyncEvent.WaitOne(allowedTileFetchTime)) + { + Assert.Fail("TileFetcher should not fire asynchronous events if tile is retrieved from cache."); + } + + mocks.VerifyAll(); + } + } + + [Test] + public void GetTile_TileFetcherDisposed_ThrowObjectDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + var tileInfo = new TileInfo(); + + // Call + TestDelegate call = () => tileFetcher.GetTile(tileInfo); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] + public void GivenTileFetcherWithoutCachedTile_WhenGettingSameTimeMultipleTimes_IgnoreDuplicateRequests() + { + // Given + var info = new TileInfo(); + var data = new byte[0]; + + using (var allRequestsDoneEvent = new ManualResetEvent(false)) + { + var tileProvider = new TileProviderStub(allRequestsDoneEvent) + { + TileDataToReturn = data + }; + + using (var fetcherIsDoneEvent = new ManualResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200)) + { + TileReceivedEventArgs receivedArguments = null; + int tileReceivedCounter = 0; + fetcher.TileReceived += (sender, args) => + { + receivedArguments = args; + tileReceivedCounter++; + }; + + int queueEmptyCounter = 0; + fetcher.QueueEmpty += (sender, args) => + { + queueEmptyCounter++; + fetcherIsDoneEvent.Set(); + }; + + // When + byte[] fetchedData1 = fetcher.GetTile(info); + byte[] fetchedData2 = fetcher.GetTile(info); + byte[] fetchedData3 = fetcher.GetTile(info); + byte[] fetchedData4 = fetcher.GetTile(info); + Assert.IsTrue(allRequestsDoneEvent.Set()); + + // Assert + if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) + { + Assert.AreEqual(1, tileProvider.GetTileCallCount); + + Assert.AreEqual(1, tileReceivedCounter); + Assert.AreSame(data, receivedArguments.Tile); + Assert.AreSame(info, receivedArguments.TileInfo); + + Assert.AreEqual(1, queueEmptyCounter); + } + else + { + Assert.Fail("TileFetcher did not respond within timelimit."); + } + + Assert.IsNull(fetchedData1, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + Assert.IsNull(fetchedData2, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + Assert.IsNull(fetchedData3, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + Assert.IsNull(fetchedData4, "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + } + } + } + + [Test] + public void GivenTileFetcherWithoutCachedTile_WhenGettingTileFailsForFirstTime_ThenTileFetcherTriesSecondTime() + { + // Setup + var info = new TileInfo(); + var data = new byte[0]; + + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + using (mocks.Ordered()) + { + int callCount = 0; + tileProvider.Stub(tp => tp.GetTile(info)) + .WhenCalled(invocation => + { + if (++callCount == 1) + { + throw new Exception("1st attempt fails."); + } + }) + .Return(data); + } + + var persistentCache = mocks.Stub>(); + persistentCache.Stub(c => c.Find(info.Index)).Return(null); + persistentCache.Expect(c => c.Add(info.Index, data)); + mocks.ReplayAll(); + + using (var fetcherIsDoneEvent = new AutoResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200, persistentCache)) + { + TileReceivedEventArgs receivedArguments = null; + int tileReceivedCounter = 0; + fetcher.TileReceived += (sender, args) => + { + receivedArguments = args; + tileReceivedCounter++; + }; + + int queueEmptyCounter = 0; + fetcher.QueueEmpty += (sender, args) => + { + queueEmptyCounter++; + fetcherIsDoneEvent.Set(); + }; + + // Call + byte[] fetchedData = fetcher.GetTile(info); + + // Assert + Assert.IsNull(fetchedData, + "Tile data hasn't been cached, so it has to be retrieved asynchronously."); + + if (fetcherIsDoneEvent.WaitOne(allowedTileFetchTime)) + { + Assert.AreEqual(1, tileReceivedCounter); + Assert.AreSame(data, receivedArguments.Tile); + Assert.AreSame(info, receivedArguments.TileInfo); + + Assert.AreEqual(1, queueEmptyCounter); + } + else + { + Assert.Fail("TileFetcher did not respond within timelimit."); + } + mocks.VerifyAll(); + } + } + + [Test] + public void DropAllPendingTileRequests_TileFetcherIsProcessingRequests_RequestsAreDropped() + { + // Setup + var info = new TileInfo(); + var data = new byte[0]; + + using (var blockingEvent = new ManualResetEvent(false)) + { + var blockingTileProvider = new TileProviderStub(blockingEvent) + { + TileDataToReturn = data + }; + + using (var fetcherIsDoneEvent = new ManualResetEvent(false)) + using (var fetcher = new AsyncTileFetcher(blockingTileProvider, 100, 200)) + { + fetcher.TileReceived += (sender, args) => + { + fetcherIsDoneEvent.Set(); + }; + fetcher.QueueEmpty += (sender, args) => + { + fetcherIsDoneEvent.Set(); + }; + + byte[] fetchedData = fetcher.GetTile(info); + + // Precondition + Assert.IsNull(fetchedData); + + // Call + fetcher.DropAllPendingTileRequests(); + + Assert.IsFalse(fetcherIsDoneEvent.WaitOne(allowedTileFetchTime), + "TileFetcher should have dropped request."); + } + } + } + + [Test] + public void DropAllPendingTileRequests_TileFetcherDisposed_ThrowObjectDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + // Call + TestDelegate call = () => tileFetcher.DropAllPendingTileRequests(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] + public void IsReady_TileFetcherIdle_ReturnTrue() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200)) + { + // Call + bool fetcherIsReady = fetcher.IsReady(); + + // Assert + Assert.IsTrue(fetcherIsReady); + mocks.VerifyAll(); + } + } + + [Test] + public void IsReady_TileFetcherHasTileRequests_ReturnFalse() + { + // Setup + using (var isReadyCalledEvent = new AutoResetEvent(false)) + { + var tileInfo = new TileInfo(); + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + tileProvider.Stub(p => p.GetTile(tileInfo)) + .WhenCalled(invocation => isReadyCalledEvent.WaitOne(100)) + .Return(null); + mocks.ReplayAll(); + + using (var fetcher = new AsyncTileFetcher(tileProvider, 100, 200)) + { + fetcher.GetTile(tileInfo); + + // Call + bool fetcherIsReady = fetcher.IsReady(); + + // Assert + isReadyCalledEvent.Set(); + + Assert.IsFalse(fetcherIsReady); + mocks.VerifyAll(); + } + } + } + + [Test] + public void IsRead_TileFetcherDisposed_ThrowObjetDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + // Call + TestDelegate call = () => tileFetcher.IsReady(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] + public void Dispose_CalledMultipleTimes_DoesNotThrow() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + + // Call + TestDelegate call = () => + { + tileFetcher.Dispose(); + tileFetcher.Dispose(); + }; + + // Assert + Assert.DoesNotThrow(call); + } + + /// + /// A stub implementation of that can wait to return + /// on its methods until an signal is given from another thread. + /// + /// Mocking this behavior in Rhinomocks leads to deadlocks. + private class TileProviderStub : ITileProvider + { + private readonly EventWaitHandle getTileShouldReturnEvent; + + public TileProviderStub(EventWaitHandle getTileShouldReturnEvent) + { + this.getTileShouldReturnEvent = getTileShouldReturnEvent; + } + + public byte[] TileDataToReturn { get; set; } + + public int GetTileCallCount { get; private set; } + + public byte[] GetTile(TileInfo tileInfo) + { + getTileShouldReturnEvent.WaitOne(); + GetTileCallCount++; + return TileDataToReturn; + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.IO.Test/Core.Components.BruTile.IO.Test.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.BruTile.IO.Test/Core.Components.BruTile.IO.Test.csproj (.../Core.Components.BruTile.IO.Test.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/test/Core.Components.BruTile.IO.Test/Core.Components.BruTile.IO.Test.csproj (.../Core.Components.BruTile.IO.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -39,20 +39,46 @@ MinimumRecommendedRules.ruleset + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + ..\..\..\..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll + True + + + ..\..\..\..\packages\RhinoMocks.3.6.1\lib\net\Rhino.Mocks.dll + True + Properties\GlobalAssembly.cs + + + Copying.Lesser.licenseheader + + + + {D749EE4C-CE50-4C17-BF01-9A953028C126} + Core.Common.TestUtil + + + {6B280C25-DB18-4F80-86D3-1CBA65208F9D} + Core.Components.BruTile.IO + + + + + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/Core.Components.BruTile.TestUtil.Test.csproj =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/Core.Components.BruTile.TestUtil.Test.csproj (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/Core.Components.BruTile.TestUtil.Test.csproj (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,104 @@ + + + + Debug + x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D} + Library + Properties + Core.Components.BruTile.TestUtil.Test + Core.Components.BruTile.TestUtil.Test + v4.0 + 512 + + + true + bin\Debug\ + 4 + x86 + MinimumRecommendedRules.ruleset + TRACE;DEBUG + full + + + bin\Release\ + 4 + x86 + MinimumRecommendedRules.ruleset + TRACE + true + none + + + bin\ReleaseForCodeCoverage\ + TRACE + true + none + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + ..\..\..\..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll + True + + + ..\..\..\..\packages\RhinoMocks.3.6.1\lib\net\Rhino.Mocks.dll + True + + + + + + + + Properties\GlobalAssembly.cs + + + + + + + + + + Copying.Lesser.licenseheader + + + + + + {3bbfd65b-b277-4e50-ae6d-bd24c3434609} + Core.Common.Base + + + {D749EE4C-CE50-4C17-BF01-9A953028C126} + Core.Common.TestUtil + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + + + {318BA582-88C9-4816-A54A-A7E431461DE3} + Core.Components.Gis + + + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Core.Components.BruTile.TestUtil + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/Properties/AssemblyInfo.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/Properties/AssemblyInfo.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/Properties/AssemblyInfo.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ +// 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Core.Components.BruTile.TestUtil.Test")] +[assembly: AssemblyProduct("Core.Components.BruTile.TestUtil.Test")] +[assembly: Guid("69b97f30-f52b-4a31-a250-7280123cff3d")] \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestTileSourceFactoryTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestTileSourceFactoryTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestTileSourceFactoryTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,86 @@ +// 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.Collections.Generic; +using System.Linq; +using BruTile; +using Core.Components.BruTile.Configurations; +using Core.Components.Gis.Data; +using NUnit.Framework; + +namespace Core.Components.BruTile.TestUtil.Test +{ + [TestFixture] + public class TestTileSourceFactoryTest + { + [Test] + public void Constructor_ForWmtsMapData_ExpectedValues() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateUnconnectedMapData(); + + // Call + var factory = new TestTileSourceFactory(mapData); + + // Assert + Assert.IsInstanceOf(factory); + } + + [Test] + public void GetWmtsTileSources_FromUninitializedWmtsMapData_ReturnEmpty() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateUnconnectedMapData(); + + // Precondition + Assert.IsFalse(mapData.IsConfigured); + + var factory = new TestTileSourceFactory(mapData); + + // Call + IEnumerable tileSources = factory.GetWmtsTileSources(null); + + // Assert + CollectionAssert.IsEmpty(tileSources); + } + + [Test] + public void GetWmtsTileSources_FromConfiguredWmtsMapData_ReturnTileSource() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateDefaultPdokMapData(); + + // Precondition + Assert.IsTrue(mapData.IsConfigured); + + var factory = new TestTileSourceFactory(mapData); + + // Call + ITileSource[] tileSources = factory.GetWmtsTileSources(null).ToArray(); + + // Assert + Assert.AreEqual(1, tileSources.Length); + ITileSource tileSource = tileSources[0]; + Assert.IsInstanceOf(tileSource); + Assert.AreEqual(mapData.PreferredFormat, tileSource.Schema.Format); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestWmtsTileSourceTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestWmtsTileSourceTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/TestWmtsTileSourceTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,105 @@ +// 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.Drawing; +using System.IO; +using BruTile; +using BruTile.Web; +using BruTile.Wmts; +using Core.Common.TestUtil; +using Core.Components.Gis.Data; +using NUnit.Framework; + +namespace Core.Components.BruTile.TestUtil.Test +{ + [TestFixture] + public class TestWmtsTileSourceTest + { + [Test] + public void Constructor_ConfiguredWmtsMapData_ExpectedValues() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateDefaultPdokMapData(); + + // Call + var source = new TestWmtsTileSource(mapData); + + // Assert + Assert.IsInstanceOf(source); + Assert.AreEqual("Stub schema", source.Name); + Assert.IsNotNull(source.Attribution); + Assert.IsNotNull(source.PersistentCache); + + WmtsTileSchema wmtsSchema = (WmtsTileSchema) source.Schema; + Assert.AreEqual(mapData.Name, wmtsSchema.Title); + Assert.AreEqual(mapData.PreferredFormat, wmtsSchema.Format); + } + + [Test] + public void Constructor_UnconfiguredWmtsMapData_ThrowArgumentException() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateUnconnectedMapData(); + + // Call + TestDelegate call = () => new TestWmtsTileSource(mapData); + + // Assert + const string message = "Only configured WmtsMapData instances can be used to create a schema for."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; + Assert.AreEqual("mapData", paramName); + } + + [Test] + public void GetTile_ForAnyTileInfo_ReturnsStubTileData() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateDefaultPdokMapData(); + var source = new TestWmtsTileSource(mapData); + + // Call + byte[] tileData = source.GetTile(new TileInfo()); + + // Assert + using (var stream = new MemoryStream(tileData)) + using (var tileImage = new Bitmap(stream)) + { + Assert.AreEqual(256, tileImage.Width); + Assert.AreEqual(256, tileImage.Height); + } + } + + [Test] + public void GetUri_ForAnyTileInfo_ReturnStubUrl() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateDefaultPdokMapData(); + var source = new TestWmtsTileSource(mapData); + + // Call + Uri url = source.GetUri(new TileInfo()); + + // Assert + Assert.AreEqual(@"https://www.stub.org/", url.ToString()); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/TileSchemaFactoryTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/TileSchemaFactoryTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/TileSchemaFactoryTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,107 @@ +// 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 BruTile; +using BruTile.Wmts; +using Core.Common.TestUtil; +using Core.Components.Gis.Data; +using NUnit.Framework; + +namespace Core.Components.BruTile.TestUtil.Test +{ + [TestFixture] + public class TileSchemaFactoryTest + { + [Test] + public void CreateWmtsTileSchema_ForWmtsMapData_ReturnsWmtsTileSchema() + { + // Setup + WmtsMapData wmtsMapData = WmtsMapData.CreateDefaultPdokMapData(); + + // Call + WmtsTileSchema schema = TileSchemaFactory.CreateWmtsTileSchema(wmtsMapData); + + // Assert + Assert.AreEqual(wmtsMapData.Name, schema.Title); + Assert.AreEqual(wmtsMapData.PreferredFormat, schema.Format); + Assert.AreEqual("brtachtergrondkaart", schema.Layer); + Assert.AreEqual("EPSG:28992", schema.TileMatrixSet); + Assert.AreEqual("EPSG:28992", schema.Srs); + + Assert.AreEqual(1, schema.Resolutions.Count); + Resolution resolution = schema.Resolutions["1"]; + Assert.AreEqual("1", resolution.Id); + Assert.AreEqual(1, resolution.UnitsPerPixel); + Assert.AreEqual(256, resolution.TileWidth); + Assert.AreEqual(256, resolution.TileHeight); + Assert.AreEqual(0, resolution.Left); + Assert.AreEqual(0, resolution.Top); + Assert.AreEqual(0, resolution.MatrixHeight); + Assert.AreEqual(0, resolution.MatrixWidth); + Assert.AreEqual(0, resolution.ScaleDenominator); + } + + [Test] + public void CreateWmtsTileSchema_ForWmtsMapDataWithoutClearCoordinateSystem_ReturnsWmtsTileSchemaAtWgs84() + { + // Setup + var mapData = new WmtsMapData("A", "B", "C(D)", "image/jpeg"); + + // Call + WmtsTileSchema schema = TileSchemaFactory.CreateWmtsTileSchema(mapData); + + // Assert + Assert.AreEqual("A", schema.Title); + Assert.AreEqual(mapData.PreferredFormat, schema.Format); + Assert.AreEqual("C", schema.Layer); + Assert.AreEqual("D", schema.TileMatrixSet); + Assert.AreEqual("EPSG:3857", schema.Srs); + + Assert.AreEqual(1, schema.Resolutions.Count); + Resolution resolution = schema.Resolutions["1"]; + Assert.AreEqual("1", resolution.Id); + Assert.AreEqual(1, resolution.UnitsPerPixel); + Assert.AreEqual(256, resolution.TileWidth); + Assert.AreEqual(256, resolution.TileHeight); + Assert.AreEqual(0, resolution.Left); + Assert.AreEqual(0, resolution.Top); + Assert.AreEqual(0, resolution.MatrixHeight); + Assert.AreEqual(0, resolution.MatrixWidth); + Assert.AreEqual(0, resolution.ScaleDenominator); + } + + [Test] + public void CreateWmtsTileSchema_ForUninitializedWmtsMapData_ThrowArgumentException() + { + // Setup + WmtsMapData mapData = WmtsMapData.CreateUnconnectedMapData(); + + // Call + TestDelegate call = () => TileSchemaFactory.CreateWmtsTileSchema(mapData); + + // Assert + const string message = "Only configured WmtsMapData instances can be used to create a schema for."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; + Assert.AreEqual("mapData", paramName); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/UseCustomTileSourceFactoryConfigTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/UseCustomTileSourceFactoryConfigTest.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/UseCustomTileSourceFactoryConfigTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,69 @@ +// 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 Core.Components.BruTile.Configurations; +using Core.Components.Gis.Data; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Components.BruTile.TestUtil.Test +{ + [TestFixture] + public class UseCustomTileSourceFactoryConfigTest + { + [Test] + public void GivenTileSourceFactoryInstance_WhenConfigForFactory_ThenSingletonInstanceTemporarilyChanged() + { + // Given + ITileSourceFactory originalFactory = TileSourceFactory.Instance; + + var mocks = new MockRepository(); + var factory = mocks.Stub(); + mocks.ReplayAll(); + + // When + using (new UseCustomTileSourceFactoryConfig(factory)) + { + // Then + Assert.AreSame(factory, TileSourceFactory.Instance); + } + Assert.AreSame(originalFactory, TileSourceFactory.Instance); + mocks.VerifyAll(); + } + + [Test] + public void GivenTileSourceFactoryInstance_WhenConfigForMapData_ThenSingletonInstanceTemporarilyChanged() + { + // Given + ITileSourceFactory originalFactory = TileSourceFactory.Instance; + + WmtsMapData mapData = WmtsMapData.CreateDefaultPdokMapData(); + + // When + using (new UseCustomTileSourceFactoryConfig(mapData)) + { + // Then + Assert.IsInstanceOf(TileSourceFactory.Instance); + } + Assert.AreSame(originalFactory, TileSourceFactory.Instance); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil.Test/packages.config =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil.Test/packages.config (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil.Test/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/Core.Components.BruTile.TestUtil.csproj =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/Core.Components.BruTile.TestUtil.csproj (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/Core.Components.BruTile.TestUtil.csproj (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,102 @@ + + + + Debug + x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Library + Properties + Core.Components.BruTile.TestUtil + Core.Components.BruTile.TestUtil + v4.0 + 512 + + + true + bin\Debug\ + 4 + x86 + MinimumRecommendedRules.ruleset + TRACE;DEBUG + full + + + bin\Release\ + 4 + x86 + MinimumRecommendedRules.ruleset + TRACE + true + none + + + bin\ReleaseForCodeCoverage\ + TRACE + true + none + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll + True + + + + + + + + Properties\GlobalAssembly.cs + + + + Resources.resx + True + True + + + + + + + + + Copying.Lesser.licenseheader + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + {3bbfd65b-b277-4e50-ae6d-bd24c3434609} + Core.Common.Base + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + + + {318BA582-88C9-4816-A54A-A7E431461DE3} + Core.Components.Gis + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/Properties/AssemblyInfo.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/Properties/AssemblyInfo.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/Properties/AssemblyInfo.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ +// 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Core.Components.BruTile.TestUtil")] +[assembly: AssemblyProduct("Core.Components.BruTile.TestUtil")] +[assembly: Guid("1081336c-d919-4249-ab33-9af15f4d19ec")] \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.Designer.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.Designer.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.Designer.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,94 @@ +// 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. + +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Core.Components.BruTile.TestUtil.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Core.Components.BruTile.TestUtil.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap stubTile { + get { + object obj = ResourceManager.GetObject("stubTile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} Index: Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.resx =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.resx (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/Properties/Resources.resx (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\stubTile.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/Resources/stubTile.png =================================================================== diff -u Binary files differ Index: Core/Components/test/Core.Components.BruTile.TestUtil/TestTileSourceFactory.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/TestTileSourceFactory.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/TestTileSourceFactory.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,59 @@ +// 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.Collections.Generic; +using BruTile; +using Core.Components.BruTile.Configurations; +using Core.Components.Gis.Data; + +namespace Core.Components.BruTile.TestUtil +{ + /// + /// A implementation suitable for unit testing purposes. + /// + public class TestTileSourceFactory : ITileSourceFactory + { + private readonly TestWmtsTileSource wmtsTileSource; + + /// + /// Initializes a new instance of for a given + /// . + /// + /// The map data to work for. + /// If isn't initialized at construction + /// time, then returns no tile sources. + public TestTileSourceFactory(WmtsMapData backgroundMapData) + { + if (backgroundMapData.IsConfigured) + { + wmtsTileSource = new TestWmtsTileSource(backgroundMapData); + } + } + + public IEnumerable GetWmtsTileSources(string capabilitiesUrl) + { + if (wmtsTileSource != null) + { + yield return wmtsTileSource; + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/TestWmtsTileSource.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/TestWmtsTileSource.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/TestWmtsTileSource.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,84 @@ +// 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.Drawing.Imaging; +using System.IO; +using BruTile; +using BruTile.Web; +using BruTile.Wmts; +using Core.Components.BruTile.TestUtil.Properties; +using Core.Components.Gis.Data; + +namespace Core.Components.BruTile.TestUtil +{ + /// + /// Defines an suitable to most unit test cases related to + /// dealing with . + /// + public class TestWmtsTileSource : HttpTileSource + { + private static byte[] pngTileDataStub; + + /// + /// Create a new instance of suitable to work for + /// a given . + /// + /// The map data to work with. + /// Thrown when isn't + /// a configured. + public TestWmtsTileSource(WmtsMapData mapData) + : base(CreateWmtsTileSchema(mapData), new RequestStub(), "Stub schema", null, GetStubTile) + { + var imageFormatExtension = mapData.PreferredFormat.Split('/')[1]; + if (imageFormatExtension != "png") + { + throw new NotImplementedException($"Please extend this class to support the '*.{imageFormatExtension}' extension."); + } + } + + private static WmtsTileSchema CreateWmtsTileSchema(WmtsMapData mapData) + { + return TileSchemaFactory.CreateWmtsTileSchema(mapData); + } + + private static byte[] GetStubTile(Uri url) + { + if (pngTileDataStub == null) + { + using (var stream = new MemoryStream()) + { + Resources.stubTile.Save(stream, ImageFormat.Png); + pngTileDataStub = stream.ToArray(); + } + } + return pngTileDataStub; + } + + private class RequestStub : IRequest + { + public Uri GetUri(TileInfo info) + { + return new Uri(@"https:\\www.stub.org"); + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/TileSchemaFactory.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/TileSchemaFactory.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/TileSchemaFactory.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,75 @@ +// 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.Text.RegularExpressions; +using BruTile; +using BruTile.Wmts; +using Core.Components.Gis.Data; + +namespace Core.Components.BruTile.TestUtil +{ + /// + /// Factory class to create instances of . + /// + public static class TileSchemaFactory + { + /// + /// Create a based on a instance. + /// + /// The data for which the schema will be based upon. + /// The newly created tile schema. + /// Thrown when isn't + /// configured. + public static WmtsTileSchema CreateWmtsTileSchema(WmtsMapData mapData) + { + if (!mapData.IsConfigured) + { + throw new ArgumentException($"Only configured {typeof(WmtsMapData).Name} instances can be used to create a schema for.", + nameof(mapData)); + } + + WmtsTileSchema schema = ConstructWmtsTileSchema(); + schema.Title = mapData.Name; + schema.Format = mapData.PreferredFormat; + + schema.Resolutions["1"] = new Resolution("1", 1); + + var capabilityIdRegex = new Regex(@"(?.+)\((?.+)\)"); + Match match = capabilityIdRegex.Match(mapData.SelectedCapabilityIdentifier); + schema.Layer = match.Groups["Layer"].Value; + schema.TileMatrixSet = match.Groups["TileMatrixSet"].Value; + + var coordinateSystemRegex = new Regex(@"EPSG:(?\d+)"); + Match potentialMatch = coordinateSystemRegex.Match(schema.TileMatrixSet); + schema.Srs = potentialMatch.Success ? + $"EPSG:{potentialMatch.Groups["SrsNumber"]}" : + "EPSG:3857"; + + return schema; + } + + private static WmtsTileSchema ConstructWmtsTileSchema() + { + return (WmtsTileSchema) Activator.CreateInstance(typeof(WmtsTileSchema), true); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/UseCustomTileSourceFactoryConfig.cs =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/UseCustomTileSourceFactoryConfig.cs (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/UseCustomTileSourceFactoryConfig.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,60 @@ +// 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 Core.Components.BruTile.Configurations; +using Core.Components.Gis.Data; + +namespace Core.Components.BruTile.TestUtil +{ + /// + /// Configures to temporarily use a different + /// instance. + /// + public sealed class UseCustomTileSourceFactoryConfig : IDisposable + { + private readonly ITileSourceFactory originalFactory; + + /// + /// Creates a new instance of . + /// + /// The temporary factory to be used. + public UseCustomTileSourceFactoryConfig(ITileSourceFactory factory) + { + originalFactory = TileSourceFactory.Instance; + TileSourceFactory.Instance = factory; + } + + /// + /// Creates a new instance of that + /// initializes test stubs to work for a instance. + /// + /// The map data to work with. + public UseCustomTileSourceFactoryConfig(WmtsMapData backgroundMapData) : this(new TestTileSourceFactory(backgroundMapData)) + { + } + + public void Dispose() + { + TileSourceFactory.Instance = originalFactory; + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.BruTile.TestUtil/packages.config =================================================================== diff -u --- Core/Components/test/Core.Components.BruTile.TestUtil/packages.config (revision 0) +++ Core/Components/test/Core.Components.BruTile.TestUtil/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Forms.Test/Core.Components.DotSpatial.Forms.Test.csproj =================================================================== diff -u -r86b2665e1dd51dc99d33568d1f4206f3da204254 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.Forms.Test/Core.Components.DotSpatial.Forms.Test.csproj (.../Core.Components.DotSpatial.Forms.Test.csproj) (revision 86b2665e1dd51dc99d33568d1f4206f3da204254) +++ Core/Components/test/Core.Components.DotSpatial.Forms.Test/Core.Components.DotSpatial.Forms.Test.csproj (.../Core.Components.DotSpatial.Forms.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -80,16 +80,8 @@ Properties\GlobalAssembly.cs - - - - - - - - @@ -124,6 +116,14 @@ {d749ee4c-ce50-4c17-bf01-9a953028c126} Core.Common.TestUtil + + {6B280C25-DB18-4F80-86D3-1CBA65208F9D} + Core.Components.BruTile.IO + + + {e02482c7-f12b-42f0-bb2b-c7ec17503a72} + Core.Components.BruTile + {5a91174a-fb95-4c9d-9ca5-81c0b8d4361a} Core.Components.DotSpatial.Forms @@ -140,6 +140,10 @@ {318ba582-88c9-4816-a54a-a7e431461de3} Core.Components.Gis + + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Core.Components.BruTile.TestUtil + {9b6f3987-eaf7-4733-80c1-3dcab44d87ae} Core.Components.DotSpatial.TestUtil Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/IO/WmtsCapabilityFactoryTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/IO/WmtsConnectionInfoReaderTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/IO/WmtsConnectionInfoTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/IO/WmtsConnectionInfoWriterTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs =================================================================== diff -u -reb95ff53a2a3010673144d34c0370632698c35ee -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs (.../MapControlTest.cs) (revision eb95ff53a2a3010673144d34c0370632698c35ee) +++ Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs (.../MapControlTest.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -31,12 +31,13 @@ using Core.Common.Base.Geometry; using Core.Common.Gui.TestUtil.Settings; using Core.Common.TestUtil; +using Core.Components.BruTile.Configurations; +using Core.Components.BruTile.TestUtil; using Core.Components.DotSpatial.Layer.BruTile; -using Core.Components.DotSpatial.Layer.BruTile.Configurations; using Core.Components.DotSpatial.MapFunctions; -using Core.Components.DotSpatial.TestUtil; using Core.Components.Gis; using Core.Components.Gis.Data; +using Core.Components.Gis.Exceptions; using Core.Components.Gis.Features; using Core.Components.Gis.Forms; using Core.Components.Gis.Geometries; @@ -2794,7 +2795,7 @@ } /// - /// Generates containing problematic . + /// Generates containing problematic . /// /// The test-name prefix. /// The data for the test cases. Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/Views/WmtsCapabilityRowTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/Views/WmtsCapabilityTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/Views/WmtsConnectionDialogTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Forms.Test/Views/WmtsLocationControlTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Components/test/Core.Components.DotSpatial.Forms.Test/WmtsBackgroundLayerStatusTest.cs =================================================================== diff -u -r974fb1eadbd8a630c7a992648ad42ac85ec205b1 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.Forms.Test/WmtsBackgroundLayerStatusTest.cs (.../WmtsBackgroundLayerStatusTest.cs) (revision 974fb1eadbd8a630c7a992648ad42ac85ec205b1) +++ Core/Components/test/Core.Components.DotSpatial.Forms.Test/WmtsBackgroundLayerStatusTest.cs (.../WmtsBackgroundLayerStatusTest.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -22,9 +22,9 @@ using System; using System.Collections.Generic; using BruTile; +using Core.Components.BruTile.Configurations; +using Core.Components.BruTile.IO; using Core.Components.DotSpatial.Layer.BruTile; -using Core.Components.DotSpatial.Layer.BruTile.Configurations; -using Core.Components.DotSpatial.Layer.BruTile.TileFetching; using Core.Components.Gis.Data; using NUnit.Framework; using Rhino.Mocks; Index: Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj (.../Core.Components.DotSpatial.Test.csproj) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj (.../Core.Components.DotSpatial.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -103,20 +103,9 @@ - - - - - - - - - - - - - - + + + @@ -140,6 +129,14 @@ {D749EE4C-CE50-4C17-BF01-9A953028C126} Core.Common.TestUtil + + {6B280C25-DB18-4F80-86D3-1CBA65208F9D} + Core.Components.BruTile.IO + + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + {aa47e858-a2a7-470e-8b2d-c76ae8ed9ccd} Core.Components.DotSpatial Index: Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/BruTileLayerTest.cs =================================================================== diff -u -rb1574f00ac2a6242a94659b08de22f8b9ee97120 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/BruTileLayerTest.cs (.../BruTileLayerTest.cs) (revision b1574f00ac2a6242a94659b08de22f8b9ee97120) +++ Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/BruTileLayerTest.cs (.../BruTileLayerTest.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -27,10 +27,10 @@ using System.Linq; using BruTile; using Core.Common.TestUtil; +using Core.Components.BruTile.Configurations; +using Core.Components.BruTile.IO; using Core.Components.DotSpatial.Layer.BruTile; -using Core.Components.DotSpatial.Layer.BruTile.Configurations; -using Core.Components.DotSpatial.Layer.BruTile.Projections; -using Core.Components.DotSpatial.Layer.BruTile.TileFetching; +using Core.Components.DotSpatial.Projections; using Core.Components.DotSpatial.Test.Properties; using DotSpatial.Controls; using DotSpatial.Projections; Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/BruTileReflectionHelperTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/CannotCreateTileCacheExceptionTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/CannotFindTileSourceExceptionTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/CannotReceiveTilesExceptionTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/PersistentCacheConfigurationTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/TileSourceFactoryTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfigurationTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WmtsLayerConfigurationTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Projections/ReprojectExtensionsTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Projections/TileReprojectorTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Projections/WorldFileTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/AsyncTileFetcherTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/NoopTileCacheTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/TileReceivedEventArgsTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Components/test/Core.Components.DotSpatial.Test/Projections/ReprojectExtensionsTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.DotSpatial.Test/Projections/ReprojectExtensionsTest.cs (revision 0) +++ Core/Components/test/Core.Components.DotSpatial.Test/Projections/ReprojectExtensionsTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,405 @@ +// 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.Linq; +using Core.Common.TestUtil; +using Core.Components.DotSpatial.Projections; +using DotSpatial.Data; +using DotSpatial.Projections; +using DotSpatial.Topology; +using NUnit.Framework; + +namespace Core.Components.DotSpatial.Test.Projections +{ + [TestFixture] + public class ReprojectExtensionsTest + { + [Test] + public void Reproject_LinearRingNull_ThrowArgumentNullException() + { + // Setup + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + ILinearRing linearRing = null; + + // Call + TestDelegate call = () => linearRing.Reproject(projection, projection); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("ring", paramName); + } + + [Test] + public void Reproject_ForLinearRingWithSourceProjectionNull_ThrowArgumentNullException() + { + // Setup + var p1 = new Coordinate(0.0, 0.0); + var p2 = new Coordinate(1.1, 1.1); + + var linearRing = new LinearRing(new[] + { + p1, + p2, + p1 + }); + + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => linearRing.Reproject(null, projection); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("source", paramName); + } + + [Test] + public void Reproject_ForLinearRingWithTargetProjectionNull_ThrowArgumentNullException() + { + // Setup + var p1 = new Coordinate(0.0, 0.0); + var p2 = new Coordinate(1.1, 1.1); + + var linearRing = new LinearRing(new[] + { + p1, + p2, + p1 + }); + + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => linearRing.Reproject(projection, null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("target", paramName); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + [TestCase(2)] + public void Reproject_ForLinearRingWithTooFewCoordinates_ThrowArgumentException(int numberOfPoints) + { + // Setup + IEnumerable coordinates = Enumerable.Range(0, numberOfPoints) + .Select(i => new Coordinate(i, i)); + var linearRing = new LinearRing(Enumerable.Empty()); + foreach (Coordinate coordinate in coordinates) + { + linearRing.Coordinates.Add(coordinate); + } + + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => linearRing.Reproject(projection, projection); + + // Assert + var message = "Ring must contain at least 3 coordinates."; + string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; + Assert.AreEqual("ring", paramName); + } + + [Test] + public void Reproject_ForLinearRingWithTargetAndSourceTheSameCoordinateSystem_DensifiedLinearRing() + { + // Setup + var p1 = new Coordinate(0.0, 0.0); + var p2 = new Coordinate(1.1, 1.1); + var p3 = new Coordinate(2.2, 0.0); + var triangleCoordinates = new[] + { + p1, + p2, + p3, + p1 + }; + var ring = new LinearRing(triangleCoordinates); + + ProjectionInfo sourceProjection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + ILinearRing reprojectedRing = ring.Reproject(sourceProjection, sourceProjection); + + // Assert + const int numberOfEdges = 3; + const int expectedNumberOfExtraPoints = 35; + Assert.AreEqual(numberOfEdges * expectedNumberOfExtraPoints + numberOfEdges + 1, reprojectedRing.Coordinates.Count); + + const double allowedError = 1e-6; // Allow small drift in reprojecting to same coordinate system. + + const int expectedP1Index = 0; + const int expectedP2Index = expectedNumberOfExtraPoints + 1; + const int expectedP3Index = 2 * (expectedNumberOfExtraPoints + 1); + const int expectedP1RepeatIndex = 3 * (expectedNumberOfExtraPoints + 1); + + AssertCoordinatesAreEqual(p1, reprojectedRing.Coordinates[expectedP1Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p1, p2, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP1Index + 1, expectedP2Index - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p2, reprojectedRing.Coordinates[expectedP2Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p2, p3, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP2Index + 1, expectedP3Index - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p3, reprojectedRing.Coordinates[expectedP3Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p3, p1, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP3Index + 1, expectedP1RepeatIndex - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p1, reprojectedRing.Coordinates[expectedP1RepeatIndex], allowedError); + } + + [Test] + public void Reproject_ForLinearRingWithDifferentCoordinateSystem_DensifiedAndReprojectedLinearRing() + { + // Setup + var p1 = new Coordinate(0.0, 0.0); + var p2 = new Coordinate(1.1, 1.1); + var p3 = new Coordinate(2.2, 0.0); + var triangleCoordinates = new[] + { + p1, + p2, + p3, + p1 + }; + var ring = new LinearRing(triangleCoordinates); + + ProjectionInfo sourceProjection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + ProjectionInfo targetProjection = KnownCoordinateSystems.Projected.World.WebMercator; + + // Call + ILinearRing reprojectedRing = ring.Reproject(sourceProjection, targetProjection); + + // Assert + const int numberOfEdges = 3; + const int expectedNumberOfExtraPoints = 35; + Assert.AreEqual(numberOfEdges * expectedNumberOfExtraPoints + numberOfEdges + 1, reprojectedRing.Coordinates.Count); + + const double allowedError = 1e-6; + + const int expectedP1Index = 0; + const int expectedP2Index = expectedNumberOfExtraPoints + 1; + const int expectedP3Index = 2 * (expectedNumberOfExtraPoints + 1); + const int expectedP1RepeatIndex = 3 * (expectedNumberOfExtraPoints + 1); + + // Note: Very rough estimates can be gotten from https://epsg.io/transform#s_srs=28992&t_srs=900913 + // Use them as sanity checks for the values below. + AssertCoordinatesAreEqual(new Coordinate(368882.53051896818, 6102740.2091378355), reprojectedRing.Coordinates[expectedP1Index], allowedError); + AssertCoordinatesAreEqual(new Coordinate(368884.12244735827, 6102741.8971153079), reprojectedRing.Coordinates[expectedP2Index], allowedError); + AssertCoordinatesAreEqual(new Coordinate(368885.80535674578, 6102740.3003927628), reprojectedRing.Coordinates[expectedP3Index], allowedError); + AssertCoordinatesAreEqual(reprojectedRing.Coordinates[expectedP1Index], reprojectedRing.Coordinates[expectedP1RepeatIndex], allowedError); + } + + [Test] + public void Reproject_ForLinearRingWithTargetCoordinateSystemWithoutTransform_ReturnDesifiedLinearRing() + { + // Setup + var p1 = new Coordinate(0.0, 0.0); + var p2 = new Coordinate(1.1, 1.1); + var p3 = new Coordinate(2.2, 0.0); + var triangleCoordinates = new[] + { + p1, + p2, + p3, + p1 + }; + var ring = new LinearRing(triangleCoordinates); + + ProjectionInfo sourceProjection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + ProjectionInfo targetProjection = new ProjectionInfo(); + targetProjection.CopyProperties(sourceProjection); + targetProjection.Transform = null; + + // Call + ILinearRing reprojectedRing = ring.Reproject(sourceProjection, sourceProjection); + + // Assert + const int numberOfEdges = 3; + const int expectedNumberOfExtraPoints = 35; + Assert.AreEqual(numberOfEdges * expectedNumberOfExtraPoints + numberOfEdges + 1, reprojectedRing.Coordinates.Count); + + const double allowedError = 1e-6; // Allow small drift in reprojecting to same coordinate system. + + const int expectedP1Index = 0; + const int expectedP2Index = expectedNumberOfExtraPoints + 1; + const int expectedP3Index = 2 * (expectedNumberOfExtraPoints + 1); + const int expectedP1RepeatIndex = 3 * (expectedNumberOfExtraPoints + 1); + + AssertCoordinatesAreEqual(p1, reprojectedRing.Coordinates[expectedP1Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p1, p2, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP1Index + 1, expectedP2Index - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p2, reprojectedRing.Coordinates[expectedP2Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p2, p3, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP2Index + 1, expectedP3Index - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p3, reprojectedRing.Coordinates[expectedP3Index], allowedError); + AssertCoordinatesAreEqual(GetExpectedExtraDesificationCoordinates(p3, p1, expectedNumberOfExtraPoints).ToArray(), + TakeElementsFromTo(reprojectedRing.Coordinates, expectedP3Index + 1, expectedP1RepeatIndex - 1).ToArray(), + allowedError); + AssertCoordinatesAreEqual(p1, reprojectedRing.Coordinates[expectedP1RepeatIndex], allowedError); + } + + [Test] + public void Reproject_ForNullExtent_ThrowArgumentNullException() + { + // Setup + Extent extent = null; + + var projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => extent.Reproject(projection, projection); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("extent", paramName); + } + + [Test] + public void Reproject_ForExtentWithSourceProjectionNull_ThrowArgumentNullException() + { + // Setup + Extent extent = new Extent(); + + var projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => extent.Reproject(null, projection); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("source", paramName); + } + + [Test] + public void Reproject_ForExtentWithTargetProjectionNull_ThrowArgumentNullException() + { + // Setup + Extent extent = new Extent(); + + var projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => extent.Reproject(projection, null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("target", paramName); + } + + [Test] + public void Reproject_ForExtentWithTargetAndSourceTheSameCoordinateSystem_ReturnEqualExtent() + { + // Setup + var extent = new Extent(1.1, 2.2, 3.3, 4.4); + + ProjectionInfo sourceProjection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + Extent result = extent.Reproject(sourceProjection, sourceProjection); + + // Assert + AssertExtentAreEqual(extent, result, 1e-6); + } + + [Test] + public void Reproject_ForExtentWithDifferentCoordinateSystems_ReturnReprojectedExtent() + { + // Setup + var extent = new Extent(1.1, 2.2, 3.3, 4.4); + + ProjectionInfo source = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + ProjectionInfo targetProjection = KnownCoordinateSystems.Projected.World.WebMercator; + + // Call + Extent result = extent.Reproject(source, targetProjection); + + // Assert + var expectedExtent = new Extent(368883.9859757676, 6102743.5394654693, 368887.35179595748, 6102746.9154212056); + AssertExtentAreEqual(expectedExtent, result, 1e-6); + } + + [Test] + public void Reproject_ForExtentWithTargetProjectionWithoutTransform_ReturnEqualExtent() + { + // Setup + var extent = new Extent(1.1, 2.2, 3.3, 4.4); + + ProjectionInfo source = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + ProjectionInfo targetProjection = new ProjectionInfo(); + targetProjection.CopyProperties(KnownCoordinateSystems.Projected.World.WebMercator); + targetProjection.Transform = null; + + // Call + Extent result = extent.Reproject(source, targetProjection); + + // Assert + AssertExtentAreEqual(extent, result, 1e-6); + } + + private void AssertExtentAreEqual(Extent expected, Extent actual, double delta) + { + Assert.AreEqual(expected.MinX, actual.MinX, delta); + Assert.AreEqual(expected.MinY, actual.MinY, delta); + Assert.AreEqual(expected.MaxX, actual.MaxX, delta); + Assert.AreEqual(expected.MaxY, actual.MaxY, delta); + } + + private static IEnumerable TakeElementsFromTo(IEnumerable coordinates, int fromIndex, int toIndex) + { + return coordinates.Skip(fromIndex).Take(toIndex - fromIndex + 1); + } + + private void AssertCoordinatesAreEqual(Coordinate expected, Coordinate actual, double delta) + { + Assert.AreEqual(expected.X, actual.X, delta); + Assert.AreEqual(expected.Y, actual.Y, delta); + } + + private void AssertCoordinatesAreEqual(IList expectedCoordinates, IList actualCoordinates, double delta) + { + Assert.AreEqual(expectedCoordinates.Count, actualCoordinates.Count); + for (int i = 0; i < expectedCoordinates.Count; i++) + { + AssertCoordinatesAreEqual(expectedCoordinates[i], actualCoordinates[i], delta); + } + } + + private IEnumerable GetExpectedExtraDesificationCoordinates(Coordinate start, Coordinate end, int expectedNumberOfAdditionalPoints) + { + double dx = (end.X - start.X) / (expectedNumberOfAdditionalPoints + 1); + double dy = (end.Y - start.Y) / (expectedNumberOfAdditionalPoints + 1); + + for (int i = 1; i <= expectedNumberOfAdditionalPoints; i++) + { + yield return new Coordinate(start.X + i * dx, start.Y + i * dy); + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Test/Projections/TileReprojectorTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.DotSpatial.Test/Projections/TileReprojectorTest.cs (revision 0) +++ Core/Components/test/Core.Components.DotSpatial.Test/Projections/TileReprojectorTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,176 @@ +// 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.Drawing; +using Core.Common.TestUtil; +using Core.Components.DotSpatial.Projections; +using Core.Components.DotSpatial.Test.Properties; +using DotSpatial.Controls; +using DotSpatial.Data; +using DotSpatial.Projections; +using NUnit.Framework; +using WorldFile = Core.Components.DotSpatial.Projections.WorldFile; + +namespace Core.Components.DotSpatial.Test.Projections +{ + [TestFixture] + public class TileReprojectorTest + { + [Test] + public void Constructor_MapArgsNull_ThrowArgumentNullException() + { + // Setup + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + + // Call + TestDelegate call = () => new TileReprojector(null, projection, projection); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("mapArgs", paramName); + } + + [Test] + public void Reproject_SourceProjectionNull_ReturnSourceMaterial() + { + // Setup + ProjectionInfo target = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + var mapArgs = new MapArgs(new Rectangle(), new Extent()); + + var projector = new TileReprojector(mapArgs, null, target); + + var sourceReference = new WorldFile(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Bitmap sourceTile = Resources.testImage; + + WorldFile targetReference; + Bitmap targetTile; + + // Call + projector.Reproject(sourceReference, sourceTile, out targetReference, out targetTile); + + // Assert + Assert.AreSame(sourceReference, targetReference); + Assert.AreSame(sourceTile, targetTile); + } + + [Test] + public void Reproject_TargetProjectionNull_ReturnSourceMaterial() + { + // Setup + ProjectionInfo source = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + var mapArgs = new MapArgs(new Rectangle(), new Extent()); + + var projector = new TileReprojector(mapArgs, source, null); + + var sourceReference = new WorldFile(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Bitmap sourceTile = Resources.testImage; + + WorldFile targetReference; + Bitmap targetTile; + + // Call + projector.Reproject(sourceReference, sourceTile, out targetReference, out targetTile); + + // Assert + Assert.AreSame(sourceReference, targetReference); + Assert.AreSame(sourceTile, targetTile); + } + + [Test] + public void Reproject_SameProjection_ReturnSourceMaterial() + { + // Setup + ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + var mapArgs = new MapArgs(new Rectangle(), new Extent()); + + var projector = new TileReprojector(mapArgs, projection, projection); + + var sourceReference = new WorldFile(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Bitmap sourceTile = Resources.testImage; + + WorldFile targetReference; + Bitmap targetTile; + + // Call + projector.Reproject(sourceReference, sourceTile, out targetReference, out targetTile); + + // Assert + Assert.AreSame(sourceReference, targetReference); + Assert.AreSame(sourceTile, targetTile); + } + + [Test] + public void Reproject_TargetTileWouldNotBeVisibleInViewport_ReturnNull() + { + // Setup + ProjectionInfo sourceProjection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel; + ProjectionInfo targetProjection = KnownCoordinateSystems.Projected.World.WebMercator; + var mapArgs = new MapArgs(new Rectangle(0,0, 10, 10), new Extent(5, 50, 10, 100)); + + var projector = new TileReprojector(mapArgs, sourceProjection, targetProjection); + + var sourceReference = new WorldFile(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Bitmap sourceTile = Resources.testImage; + + WorldFile targetReference; + Bitmap targetTile; + + // Call + projector.Reproject(sourceReference, sourceTile, out targetReference, out targetTile); + + // Assert + Assert.IsNull(targetReference); + Assert.IsNull(targetTile); + } + + [Test] + public void Reproject_DifferentCoodinateSystems_ReprojectImageAndMetaData() + { + // Setup + var mapArgs = new MapArgs(new Rectangle(0, 0, 722, 349), + new Extent(520981.864447542, 6853700.54100246, 709995.365081098, 6945065.79269375)); + var sourceProjection = ProjectionInfo.FromEpsgCode(25831); + var targetProjection = KnownCoordinateSystems.Projected.World.WebMercator; + var projector = new TileReprojector(mapArgs, sourceProjection, targetProjection); + + WorldFile sourceReference = new WorldFile(140, 0.0, 0.0, -140, 641716.59261121, 5825498); + Bitmap sourceTile = Resources.source; + + WorldFile targetReference; + Bitmap targetTile; + + // Call + projector.Reproject(sourceReference, sourceTile, out targetReference, out targetTile); + + // Assert + // Note: These ground truth values have been defined using https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Reprojection/TileReprojector.cs + Assert.AreEqual(261.791552124038, targetReference.A11, 1e-8); + Assert.AreEqual(0.0, targetReference.A21); + Assert.AreEqual(0.0, targetReference.A12); + Assert.AreEqual(-261.79155212403651, targetReference.A22, 1e-8); + Assert.AreEqual(564962.84520438069, targetReference.B1, 1e-8); + Assert.AreEqual(6902131.9781454066, targetReference.B2, 1e-8); + + TestHelper.AssertImagesAreEqual(Resources.target, targetTile); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Test/Projections/WorldFileTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.DotSpatial.Test/Projections/WorldFileTest.cs (revision 0) +++ Core/Components/test/Core.Components.DotSpatial.Test/Projections/WorldFileTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,172 @@ +// 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 Core.Common.TestUtil; +using Core.Components.DotSpatial.Projections; +using DotSpatial.Topology; +using NUnit.Framework; + +namespace Core.Components.DotSpatial.Test.Projections +{ + [TestFixture] + public class WorldFileTest + { + [Test] + public void Constructor_ExpectedValues() + { + // Call + var worldFile = new WorldFile(1.1, 2.2, 3.3, 4.4, 5.5, 6.6); + + // Assert + Assert.AreEqual(1.1, worldFile.A11); + Assert.AreEqual(2.2, worldFile.A21); + Assert.AreEqual(3.3, worldFile.A12); + Assert.AreEqual(4.4, worldFile.A22); + + Assert.AreEqual(5.5, worldFile.B1); + Assert.AreEqual(6.6, worldFile.B2); + } + + + [Test] + public void Constructor_NonInvertableTransformationSpecified_ThrowArgumentException() + { + // Call + TestDelegate call = () => new WorldFile(0.0, 0.0, 0.0, 0.0, 1.1, 2.2); + + // Assert + string message = "Ongeldige transformatie parameters: transformatie moet omkeerbaar zijn."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message); + } + + [Test] + [TestCase(1.0, -1.0, 5.5, 6.6)] + [TestCase(1.1, 2.2, 3.3, 4.4)] + public void ToWorldCoordinates_InitializedForSimpleTransformation_ReturnExpectedLocation(double scaleFactorX, double scaleFactorY, double translationX, double translationY) + { + // Setup + var worldFile = new WorldFile(scaleFactorX, 0.0, 0.0, scaleFactorY, translationX, translationY); + + const int x = 1; + const int y = 2; + + // Call + Coordinate worldPoint = worldFile.ToWorldCoordinates(x, y); + + // Assert + var expectedX = scaleFactorX * x + translationX; + var expectedY = scaleFactorY * y + translationY; + Assert.AreEqual(expectedX, worldPoint.X); + Assert.AreEqual(expectedY, worldPoint.Y); + } + + [Test] + [TestCase(0.0)] + [TestCase(Math.PI)] + public void ToWorldCoordinates_InitializedForSimpleRotation_ReturnExpectedLocation(double radian) + { + // Setup + const int x = 1; + const int y = 2; + + // 2D Rotation matrix: + double a11 = Math.Cos(radian); + double a21 = Math.Sin(radian); + double a12 = -Math.Sin(radian); + double a22 = Math.Cos(radian); + + var worldFile = new WorldFile(a11, a21, a12, a22, 0.0, 0.0); + + // Call + Coordinate worldPoint = worldFile.ToWorldCoordinates(x, y); + + // Assert + var expectedX = a11 * x + a21 * y; + var expectedY = a12 * x + a22 * y; + Assert.AreEqual(expectedX, worldPoint.X); + Assert.AreEqual(expectedY, worldPoint.Y); + } + + [Test] + public void ToScreenCoordinates_CoordinateNull_ThrowArgumentNullException() + { + // Setup + var worldFile = new WorldFile(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + + // Call + TestDelegate call = () => worldFile.ToScreenCoordinates(null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("point", paramName); + } + + [Test] + public void GivenScreenSpaceCoordinate_WhenDoingRoundtripTransformation_ThenScreenSpaceCoordinateRemainsUnchanged() + { + // Given + double a11 = 1.1; + double a21 = 2.2; + double a12 = 3.3; + double a22 = 4.4; + double transformationX = 5.5; + double transformationY = 6.6; + + var worldFile = new WorldFile(a11, a21, a12, a22, transformationX, transformationY); + + const int x = 20; + const int y = 17; + + // When + Coordinate worldCoordinate = worldFile.ToWorldCoordinates(x, y); + System.Drawing.Point screenCoordinate = worldFile.ToScreenCoordinates(worldCoordinate); + + // Assert + Assert.AreEqual(x, screenCoordinate.X); + Assert.AreEqual(y, screenCoordinate.Y); + } + + + [Test] + [TestCase(10, 20)] + [TestCase(-50, -70)] + public void BoundingOrdinatesToWorldCoordinates_ForVariousArguments_ReturnPolygonInWorldCoordinates(int width, int height) + { + // Setup + var worldFile = new WorldFile(1.1, 2.2, 3.3, 4.4, 5.5, 6.6); + + // Call + IPolygon polygon = worldFile.BoundingOrdinatesToWorldCoordinates(width, height); + + // Assert + Coordinate p1 = worldFile.ToWorldCoordinates(0, 0); + Coordinate p2 = worldFile.ToWorldCoordinates(0, height); + Coordinate p3 = worldFile.ToWorldCoordinates(width, 0); + Coordinate p4 = worldFile.ToWorldCoordinates(width, height); + CollectionAssert.IsEmpty(polygon.Holes); + CollectionAssert.AreEqual(new[] + { + p1, p2, p3, p4, p1 + }, polygon.Shell.Coordinates); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/Core.Components.DotSpatial.TestUtil.Test.csproj =================================================================== diff -u -rc67344d2d2fd13f652e674a391c6fbb5e188cd26 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/Core.Components.DotSpatial.TestUtil.Test.csproj (.../Core.Components.DotSpatial.TestUtil.Test.csproj) (revision c67344d2d2fd13f652e674a391c6fbb5e188cd26) +++ Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/Core.Components.DotSpatial.TestUtil.Test.csproj (.../Core.Components.DotSpatial.TestUtil.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -40,10 +40,6 @@ MinimumRecommendedRules.ruleset - - ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll - True - ..\..\..\..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll True @@ -62,10 +58,6 @@ - - - - Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/TestTileSourceFactoryTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/TestWmtsTileSourceTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/TileSchemaFactoryTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 99f9004206bfb9de084275d749b7aeccafd6da18 refers to a dead (removed) revision in file `Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/UseCustomTileSourceFactoryConfigTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/packages.config =================================================================== diff -u -r6e93798b2be731889dadc6c50247ea16f4d13d9c -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/packages.config (.../packages.config) (revision 6e93798b2be731889dadc6c50247ea16f4d13d9c) +++ Core/Components/test/Core.Components.DotSpatial.TestUtil.Test/packages.config (.../packages.config) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -22,7 +22,6 @@ All rights reserved. --> - \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.TestUtil/Core.Components.DotSpatial.TestUtil.csproj =================================================================== diff -u -rc67344d2d2fd13f652e674a391c6fbb5e188cd26 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.DotSpatial.TestUtil/Core.Components.DotSpatial.TestUtil.csproj (.../Core.Components.DotSpatial.TestUtil.csproj) (revision c67344d2d2fd13f652e674a391c6fbb5e188cd26) +++ Core/Components/test/Core.Components.DotSpatial.TestUtil/Core.Components.DotSpatial.TestUtil.csproj (.../Core.Components.DotSpatial.TestUtil.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -38,10 +38,6 @@ 4 - - ..\..\..\..\packages\BruTile.0.19.0\lib\net40\BruTile.dll - True - @@ -51,16 +47,7 @@ Properties\GlobalAssembly.cs - - True - True - Resources.resx - - - - - @@ -81,17 +68,7 @@ Copying.Lesser.licenseheader - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - + \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/Properties/AssemblyInfo.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/Properties/AssemblyInfo.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/Properties/AssemblyInfo.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,27 @@ +// 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Core.Components.GIS.Forms.Test")] +[assembly: AssemblyProduct("Core.Components.GIS.Forms.Test")] +[assembly: Guid("fc8f3315-e129-44ad-8a0e-f7979094ee4c")] \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsCapabilityRowTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsCapabilityRowTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsCapabilityRowTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,63 @@ +// 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 Core.Components.Gis.Forms.Views; +using NUnit.Framework; + +namespace Core.Components.Gis.Forms.Test.Views +{ + [TestFixture] + public class WmtsCapabilityRowTest + { + [Test] + public void Constructor_WmtsCapabilityNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => new WmtsCapabilityRow(null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("wmtsCapability", paramName); + } + + [Test] + public void Constructor_ValidWmtsCapability_ExpectedProperties() + { + // Setup + const string id = "laag1(abc)"; + const string format = "image/png"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + var wmtsCapability = new WmtsCapability(id, format, title, coordinateSystem); + + // Call + var row = new WmtsCapabilityRow(wmtsCapability); + + // Assert + Assert.AreEqual(id, row.Id); + Assert.AreEqual(format, row.Format); + Assert.AreEqual(title, row.Title); + Assert.AreEqual(coordinateSystem, row.CoordinateSystem); + Assert.AreSame(wmtsCapability, row.WmtsCapability); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsConnectionDialogTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsConnectionDialogTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsConnectionDialogTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,316 @@ +// 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.Threading; +using System.Windows.Forms; +using Core.Common.Controls.Dialogs; +using Core.Components.Gis.Forms.Views; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Components.Gis.Forms.Test.Views +{ + [TestFixture] + public class WmtsConnectionDialogTest : NUnitFormTest + { + [Test] + public void Constructor_WithoutDialogParent_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => new WmtsConnectionDialog(null); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("dialogParent", paramName); + } + + [Test] + public void WmtsConnectionInfoConstructor_WithoutDialogParent_ThrowsArgumentNullException() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + + // Call + TestDelegate test = () => new WmtsConnectionDialog(null, info); + + // Assert + string paramName = Assert.Throws(test).ParamName; + Assert.AreEqual("dialogParent", paramName); + } + + [Test] + public void Constructor_WithDialogParent_ExpectedProperties() + { + // Setup + var mocks = new MockRepository(); + var dialogParent = mocks.StrictMock(); + mocks.ReplayAll(); + + // Call + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + // Assert + Assert.IsInstanceOf(dialog); + Assert.IsNull(dialog.WmtsConnectionName); + Assert.IsNull(dialog.WmtsConnectionUrl); + + Assert.AreEqual("Nieuwe WMTS locatie toevoegen", dialog.Text); + + var nameLabel = new LabelTester("nameLabel", dialog); + Assert.AreEqual("Omschrijving:", nameLabel.Text); + + var urlLabel = new LabelTester("urlLabel", dialog); + Assert.AreEqual("URL:", urlLabel.Text); + + var actionButton = (Button) new ButtonTester("actionButton", dialog).TheObject; + Assert.AreEqual("Toevoegen", actionButton.Text); + Assert.IsFalse(actionButton.Enabled); + + var cancelButton = new ButtonTester("cancelButton", dialog); + Assert.AreEqual("Annuleren", cancelButton.Text); + + var nameTextBox = new TextBoxTester("nameTextBox", dialog); + Assert.IsEmpty(nameTextBox.Text); + + var urlTextBox = new TextBoxTester("urlTextBox", dialog); + Assert.IsEmpty(urlTextBox.Text); + } + + mocks.VerifyAll(); + } + + [Test] + public void WmtsConnectionInfoConstructor_WithDialogParent_ExpectedProperties() + { + // Setup + var mocks = new MockRepository(); + var dialogParent = mocks.StrictMock(); + mocks.ReplayAll(); + const string connectionName = @"name"; + const string connectionUrl = @"url"; + var info = new WmtsConnectionInfo(connectionName, connectionUrl); + + // Call + using (var dialog = new WmtsConnectionDialog(dialogParent, info)) + { + // Assert + Assert.IsInstanceOf(dialog); + Assert.IsNull(dialog.WmtsConnectionName); + Assert.IsNull(dialog.WmtsConnectionUrl); + + Assert.AreEqual("WMTS locatie aanpassen", dialog.Text); + + var nameLabel = new LabelTester("nameLabel", dialog); + Assert.AreEqual("Omschrijving:", nameLabel.Text); + + var urlLabel = new LabelTester("urlLabel", dialog); + Assert.AreEqual("URL:", urlLabel.Text); + + var actionButton = (Button) new ButtonTester("actionButton", dialog).TheObject; + Assert.AreEqual("Bewerken", actionButton.Text); + Assert.IsTrue(actionButton.Enabled); + + var cancelButton = new ButtonTester("cancelButton", dialog); + Assert.AreEqual("Annuleren", cancelButton.Text); + + var nameTextBox = new TextBoxTester("nameTextBox", dialog); + Assert.AreEqual(connectionName, nameTextBox.Text); + + var urlTextBox = new TextBoxTester("urlTextBox", dialog); + Assert.AreEqual(connectionUrl, urlTextBox.Text); + } + + mocks.VerifyAll(); + } + + [Test] + [Apartment(ApartmentState.STA)] + public void ShowDialog_DefaultProperties() + { + // Setup + DialogBoxHandler = (name, wnd) => + { + using (new FormTester(name)) {} + }; + + using (var dialogParent = new Form()) + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + // Call + dialog.ShowDialog(); + + // Assert + Assert.AreEqual(400, dialog.MinimumSize.Width); + Assert.AreEqual(150, dialog.MinimumSize.Height); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void ActionButton_WithoutValidText_ButtonIsDisabled( + [Values("", " ", null)] string name, + [Values("", " ", null)] string url) + { + // Setup + DialogBoxHandler = (formName, wnd) => + { + using (new FormTester(formName)) {} + }; + + using (var dialogParent = new Form()) + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + dialog.ShowDialog(); + + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", dialog).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", dialog).TheObject; + var actionButton = (Button) new ButtonTester("actionButton", dialog).TheObject; + + // Call + nameTextBox.Text = name; + urlTextBox.Text = url; + + // Assert + Assert.IsFalse(actionButton.Enabled); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void ActionButton_WithValidText_ButtonIsEnabled() + { + // Setup + DialogBoxHandler = (formName, wnd) => + { + using (new FormTester(formName)) {} + }; + + using (var dialogParent = new Form()) + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + dialog.ShowDialog(); + + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", dialog).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", dialog).TheObject; + var actionButton = (Button) new ButtonTester("actionButton", dialog).TheObject; + + // Call + nameTextBox.Text = @"nameTextBox"; + urlTextBox.Text = @"urlTextBox"; + + // Assert + Assert.IsTrue(actionButton.Enabled); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void ActionButtonCick_WithValidText_SetsPropertiesAndClosesForm() + { + // Setup + const string urltextbox = @"urlTextBox"; + const string nametextbox = @"nameTextBox"; + + DialogBoxHandler = (formName, wnd) => + { + using (new FormTester(formName)) + { + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", formName).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", formName).TheObject; + nameTextBox.Text = nametextbox; + urlTextBox.Text = urltextbox; + + var actionButton = new ButtonTester("actionButton", formName); + + // Call + actionButton.Click(); + } + }; + + using (var dialogParent = new Form()) + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + DialogResult dialogResult = dialog.ShowDialog(); + + // Assert + Assert.AreEqual(nametextbox, dialog.WmtsConnectionName); + Assert.AreEqual(urltextbox, dialog.WmtsConnectionUrl); + Assert.AreEqual(DialogResult.OK, dialogResult); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenValidDialog_WhenCancelPressed_ThenWmtsConnectionDataNull() + { + // Given + Button cancelButton = null; + + DialogBoxHandler = (name, wnd) => + { + using (new FormTester(name)) + { + var button = new ButtonTester("cancelButton", name); + cancelButton = (Button) button.TheObject; + button.Click(); + } + }; + + using (var dialogParent = new Form()) + using (var dialog = new WmtsConnectionDialog(dialogParent)) + { + // When + DialogResult dialogResult = dialog.ShowDialog(); + + // Then + Assert.IsNull(dialog.WmtsConnectionName); + Assert.IsNull(dialog.WmtsConnectionUrl); + + Assert.AreEqual(dialog.CancelButton, cancelButton); + Assert.AreEqual(DialogResult.Cancel, dialogResult); + } + } + + [Test] + public void Dispose_AlreadyDisposed_DoesNotThrowException() + { + // Setup + var mocks = new MockRepository(); + var dialogParent = mocks.StrictMock(); + mocks.ReplayAll(); + + // Call + TestDelegate call = () => + { + using (var control = new WmtsConnectionDialog(dialogParent)) + { + control.Dispose(); + } + }; + + // Assert + Assert.DoesNotThrow(call); + mocks.VerifyAll(); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsLocationControlTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsLocationControlTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/Views/WmtsLocationControlTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,986 @@ +// 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 System.Threading; +using System.Windows.Forms; +using BruTile; +using BruTile.Wmts; +using Core.Common.Controls.DataGrid; +using Core.Common.Gui.Settings; +using Core.Common.Gui.TestUtil.Settings; +using Core.Common.TestUtil; +using Core.Components.BruTile.Configurations; +using Core.Components.BruTile.TestUtil; +using Core.Components.Gis.Data; +using Core.Components.Gis.Exceptions; +using Core.Components.Gis.Forms.Views; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Components.Gis.Forms.Test.Views +{ + [TestFixture] + public class WmtsLocationControlTest : NUnitFormTest + { + private const int mapLayerIdColumnIndex = 0; + private const int mapLayerFormatColumnIndex = 1; + private const int mapLayerTitleColumnIndex = 2; + private const int mapLayerCoordinateSystemColumnIndex = 3; + private const string wmtsconnectioninfoConfigFile = "wmtsConnectionInfo.config"; + + private static readonly TestDataPath testPath = TestDataPath.Core.Components.DotSpatial.Forms; + + private MockRepository mockRepository; + private ITileSourceFactory tileFactory; + private IWmtsCapabilityFactory wmtsCapabilityFactory; + + [SetUp] + public void SetUp() + { + mockRepository = new MockRepository(); + tileFactory = mockRepository.StrictMock(); + wmtsCapabilityFactory = mockRepository.StrictMock(); + } + + [TearDown] + public override void TearDown() + { + mockRepository.VerifyAll(); + base.TearDown(); + } + + [Test] + public void Constructor_WmtsCapabilityFactoryNull_ThrowArgumentNullException() + { + // Setup + mockRepository.ReplayAll(); + + // Call + TestDelegate test = () => new WmtsLocationControl(null, null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("wmtsCapabilityFactory", exception.ParamName); + } + + [Test] + public void Constructor_ActiveWmtsMapDataNull_DefaultValues() + { + // Setup + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + // Assert + Assert.IsInstanceOf(control); + Assert.IsInstanceOf(control); + Assert.AreEqual("Web Map Tile Service (WMTS)", control.DisplayName); + Assert.IsNull(control.SelectedMapData); + Assert.AreSame(control, control.UserControl); + } + } + } + + [Test] + public void Constructor_ValidWmtsMapData_ExpectedProperties() + { + // Setup + WmtsMapData activeWmtsMapData = WmtsMapData.CreateDefaultPdokMapData(); + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(activeWmtsMapData.SourceCapabilitiesUrl)).Return(new[] + { + CreateWmtsCapability(new TestWmtsTileSource(activeWmtsMapData)) + }); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + using (var control = new WmtsLocationControl(activeWmtsMapData, wmtsCapabilityFactory)) + { + // Assert + AssertAreEqual(activeWmtsMapData, control.SelectedMapData); + } + } + } + + [Test] + public void Show_AddedToForm_DefaultProperties() + { + // Setup + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + using (var form = new Form()) + { + // Call + form.Controls.Add(control); + + // Assert + var urlLocationLabel = new LabelTester("urlLocationLabel", form); + Assert.AreEqual("Locatie (URL)", urlLocationLabel.Text); + + var urlLocations = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + Assert.AreEqual(ComboBoxStyle.DropDownList, urlLocations.DropDownStyle); + Assert.IsInstanceOf>(urlLocations.DataSource); + Assert.AreEqual("Name", urlLocations.DisplayMember); + Assert.AreEqual("Url", urlLocations.ValueMember); + Assert.IsTrue((bool) urlLocations.Sorted); + Assert.IsNull(urlLocations.SelectedItem); + + var buttonConnectTo = (Button) new ButtonTester("connectToButton", form).TheObject; + Assert.AreEqual("Verbinding maken", buttonConnectTo.Text); + Assert.IsFalse((bool) buttonConnectTo.Enabled); + + var buttonAddLocation = new ButtonTester("addLocationButton", form); + Assert.AreEqual("Locatie toevoegen...", buttonAddLocation.Text); + + var buttonEditLocation = (Button) new ButtonTester("editLocationButton", form).TheObject; + Assert.AreEqual("Locatie aanpassen...", buttonEditLocation.Text); + } + } + + [Test] + public void Show_AddedToFormWithWmtsMapData_DefaultProperties() + { + // Setup + WmtsMapData activeWmtsMapData = WmtsMapData.CreateDefaultPdokMapData(); + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(activeWmtsMapData.SourceCapabilitiesUrl)) + .Return(new[] + { + CreateWmtsCapability(new TestWmtsTileSource(activeWmtsMapData)) + }); + mockRepository.ReplayAll(); + + var activeWmtsConnectionInfo = new WmtsConnectionInfo(activeWmtsMapData.Name, activeWmtsMapData.SourceCapabilitiesUrl); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var control = new WmtsLocationControl(activeWmtsMapData, wmtsCapabilityFactory)) + using (var form = new Form()) + { + // Call + form.Controls.Add(control); + + // Assert + var urlLocationLabel = new LabelTester("urlLocationLabel", form); + Assert.AreEqual("Locatie (URL)", urlLocationLabel.Text); + + var urlLocations = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + Assert.AreEqual(ComboBoxStyle.DropDownList, urlLocations.DropDownStyle); + var connectionInfos = (List) urlLocations.DataSource; + Assert.Contains(activeWmtsConnectionInfo, connectionInfos); + + Assert.AreEqual("Name", urlLocations.DisplayMember); + Assert.AreEqual("Url", urlLocations.ValueMember); + Assert.IsTrue(urlLocations.Sorted); + Assert.IsNotNull(urlLocations.SelectedItem); + + var buttonConnectTo = (Button) new ButtonTester("connectToButton", form).TheObject; + Assert.AreEqual("Verbinding maken", buttonConnectTo.Text); + Assert.IsTrue(buttonConnectTo.Enabled); + } + } + + [Test] + public void Constructor_NullMapData_DataGridViewCorrectlyInitialized() + { + // Call + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + using (var form = new Form()) + { + form.Controls.Add(control); + + // Assert + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + var dataGridView = dataGridViewControl.Controls.OfType().First(); + + Assert.AreEqual(DataGridViewSelectionMode.FullRowSelect, dataGridViewControl.SelectionMode); + Assert.IsFalse(dataGridViewControl.MultiSelect); + Assert.AreEqual(4, dataGridView.ColumnCount); + + var mapLayerIdColumn = (DataGridViewTextBoxColumn) dataGridViewControl.GetColumnFromIndex(mapLayerIdColumnIndex); + Assert.AreEqual("Kaartlaag", mapLayerIdColumn.HeaderText); + Assert.AreEqual("Id", mapLayerIdColumn.DataPropertyName); + Assert.IsTrue(mapLayerIdColumn.ReadOnly); + + var mapLayerFormatColumn = (DataGridViewTextBoxColumn) dataGridViewControl.GetColumnFromIndex(mapLayerFormatColumnIndex); + Assert.AreEqual("Formaat", mapLayerFormatColumn.HeaderText); + Assert.AreEqual("Format", mapLayerFormatColumn.DataPropertyName); + Assert.IsTrue(mapLayerFormatColumn.ReadOnly); + + var mapLayerTitleColumn = (DataGridViewTextBoxColumn) dataGridViewControl.GetColumnFromIndex(mapLayerTitleColumnIndex); + Assert.AreEqual("Titel", mapLayerTitleColumn.HeaderText); + Assert.AreEqual("Title", mapLayerTitleColumn.DataPropertyName); + Assert.IsTrue(mapLayerTitleColumn.ReadOnly); + + var mapLayerCoordinateSystemColumn = (DataGridViewTextBoxColumn) dataGridViewControl.GetColumnFromIndex(mapLayerCoordinateSystemColumnIndex); + Assert.AreEqual("Coördinatenstelsel", mapLayerCoordinateSystemColumn.HeaderText); + Assert.AreEqual("CoordinateSystem", mapLayerCoordinateSystemColumn.DataPropertyName); + Assert.IsTrue(mapLayerCoordinateSystemColumn.ReadOnly); + } + } + + [Test] + public void Constructor_ValidMapDataWithITileSources_ExpectedDataGrid() + { + // Setup + WmtsMapData activeWmtsMapData = WmtsMapData.CreateDefaultPdokMapData(); + + var capabilities = new[] + { + CreateWmtsCapability(new TestWmtsTileSource(WmtsMapData.CreateAlternativePdokMapData())), + CreateWmtsCapability(new TestWmtsTileSource(activeWmtsMapData)) + }; + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(activeWmtsMapData.SourceCapabilitiesUrl)).Return(capabilities); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + using (var control = new WmtsLocationControl(activeWmtsMapData, wmtsCapabilityFactory)) + using (var form = new Form()) + { + form.Controls.Add(control); + + // Assert + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + Assert.AreEqual(2, dataGridViewControl.Rows.Count); + DataGridViewRow currentRow = dataGridViewControl.CurrentRow; + Assert.IsNotNull(currentRow); + Assert.AreEqual(1, currentRow.Cells[0].RowIndex); + } + } + } + + [Test] + public void Constructor_ValidMapDataWithoutITileSources_DataGridEmpty() + { + // Setup + WmtsMapData activeWmtsMapData = WmtsMapData.CreateDefaultPdokMapData(); + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(activeWmtsMapData.SourceCapabilitiesUrl)).Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + using (var control = new WmtsLocationControl(activeWmtsMapData, wmtsCapabilityFactory)) + using (var form = new Form()) + { + form.Controls.Add(control); + + // Assert + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + Assert.IsEmpty(dataGridViewControl.Rows); + } + } + } + + [Test] + public void Dispose_AlreadyDisposed_DoesNotThrowException() + { + // Setup + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + TestDelegate call = () => + { + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + control.Dispose(); + } + }; + + // Assert + Assert.DoesNotThrow(call); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void WmtsLocationControl_WithData_DataGridViewCorrectlyInitialized() + { + // Setup + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)) + .IgnoreArguments() + .Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (var form = new Form()) + { + // Call + using (ShowFullyConfiguredWmtsLocationControl(form, wmtsCapabilityFactory)) + { + // Assert + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + DataGridViewRowCollection rows = dataGridViewControl.Rows; + Assert.AreEqual(2, rows.Count); + + DataGridViewCellCollection cells = rows[0].Cells; + Assert.AreEqual(4, cells.Count); + Assert.AreEqual("-", cells[mapLayerIdColumnIndex].FormattedValue); + Assert.AreEqual("image/png", cells[mapLayerFormatColumnIndex].FormattedValue); + Assert.AreEqual("-", cells[mapLayerTitleColumnIndex].FormattedValue); + Assert.AreEqual("-", cells[mapLayerCoordinateSystemColumnIndex].FormattedValue); + + cells = rows[1].Cells; + Assert.AreEqual(4, cells.Count); + Assert.AreEqual("brtachtergrondkaart(EPSG:28992)", cells[mapLayerIdColumnIndex].FormattedValue); + Assert.AreEqual("image/png8", cells[mapLayerFormatColumnIndex].FormattedValue); + Assert.AreEqual("brtachtergrondkaart", cells[mapLayerTitleColumnIndex].FormattedValue); + Assert.AreEqual("EPSG:28992", cells[mapLayerCoordinateSystemColumnIndex].FormattedValue); + } + } + } + + [Test] + public void GetSelectedMapData_WithoutSelectedData_ReturnsNull() + { + // Setup + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + // Call + MapData selectedMapData = control.SelectedMapData; + + // Assert + Assert.IsNull(selectedMapData); + } + } + + [Test] + public void GetSelectedMapData_WithSelectedComboBoxWithoutSelectedRow_ReturnsNull() + { + // Setup + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)).IgnoreArguments().Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (var form = new Form()) + using (WmtsLocationControl control = ShowFullyConfiguredWmtsLocationControl(form, wmtsCapabilityFactory)) + { + // Call + MapData selectedMapData = control.SelectedMapData; + + // Assert + Assert.IsNull(selectedMapData); + } + } + + [Test] + public void GetSelectedMapData_WithSelectedData_ReturnsSelectedMapData() + { + // Setup + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)).IgnoreArguments().Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (var form = new Form()) + using (WmtsLocationControl control = ShowFullyConfiguredWmtsLocationControl(form, wmtsCapabilityFactory)) + { + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + dataGridViewControl.SetCurrentCell(dataGridViewControl.GetCell(1, 0)); + + // Call + WmtsMapData selectedMapData = control.SelectedMapData; + + // Assert + Assert.IsNotNull(selectedMapData); + Assert.AreEqual("PDOK achtergrondkaart", selectedMapData.Name); + Assert.AreEqual("brtachtergrondkaart(EPSG:28992)", selectedMapData.SelectedCapabilityIdentifier); + Assert.AreEqual("https://geodata.nationaalgeoregister.nl/wmts/top10nlv2?VERSION=1.0.0&request=GetCapabilities", + selectedMapData.SourceCapabilitiesUrl); + Assert.AreEqual("image/png8", selectedMapData.PreferredFormat); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenValidWmtsConnectionInfos_WhenConstructed_ThenExpectedProperties() + { + // Given + mockRepository.ReplayAll(); + + var settingsHelper = new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath) + }; + settingsHelper.SetApplicationVersion("twoValidWmtsConnectionInfos"); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(settingsHelper)) + { + // When + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + using (var form = new Form()) + { + form.Controls.Add(control); + + // Then + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(2, dataSource.Count); + + var firstWmtsConnectionInfo = (WmtsConnectionInfo) comboBox.Items[0]; + Assert.AreEqual("Actueel Hoogtebestand Nederland (AHN1)", firstWmtsConnectionInfo.Name); + Assert.AreEqual("https://geodata.nationaalgeoregister.nl/tiles/service/wmts/ahn1?request=GetCapabilities", + firstWmtsConnectionInfo.Url); + + var secondWmtsConnectionInfo = (WmtsConnectionInfo) comboBox.Items[1]; + Assert.AreEqual("Zeegraskartering", secondWmtsConnectionInfo.Name); + Assert.AreEqual("https://geodata.nationaalgeoregister.nl/zeegraskartering/wfs?request=GetCapabilities", + secondWmtsConnectionInfo.Url); + } + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenInvalidWmtsConnectionInfos_WhenConstructed_ThenLogGenerated() + { + // Given + mockRepository.ReplayAll(); + + var settingsHelper = new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath) + }; + settingsHelper.SetApplicationVersion("WmtsConnectionInfosWithoutWmtsConnectionsElement"); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(settingsHelper)) + { + // When + Action action = () => + { + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + using (var form = new Form()) + { + form.Controls.Add(control); + + // Then + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(0, dataSource.Count); + } + }; + + string wmtsConnectionInfoConfig = Path.Combine(TestHelper.GetTestDataPath( + testPath, + "WmtsConnectionInfosWithoutWmtsConnectionsElement"), + "wmtsConnectionInfo.config"); + var expectedMessage = $"Fout bij het lezen van bestand '{wmtsConnectionInfoConfig}': " + + "het bestand kon niet worden geopend. Mogelijk is het bestand corrupt of in gebruik door een andere applicatie."; + TestHelper.AssertLogMessageWithLevelIsGenerated(action, Tuple.Create(expectedMessage, LogLevelConstant.Error)); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndAddLocationClicked_WhenDialogCanceled_ThenWmtsLocationsNotUpdated() + { + // + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (new FormTester(formName)) {} + }; + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + var buttonAddLocation = new ButtonTester("addLocationButton", form); + + // When + buttonAddLocation.Click(); + + // Then + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(0, dataSource.Count); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndAddLocationClicked_WhenValidDataInDialog_ThenWmtsLocationsUpdated() + { + // Given + const string name = @"someName"; + const string url = @"someUrl"; + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(url)).Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (var formTester = new FormTester(formName)) + { + var dialog = (WmtsConnectionDialog) formTester.TheObject; + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", dialog).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", dialog).TheObject; + var actionButton = new ButtonTester("actionButton", dialog); + + nameTextBox.Text = name; + urlTextBox.Text = url; + + actionButton.Click(); + } + }; + + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (new FileDisposeHelper(Path.Combine(SettingsHelper.Instance.GetApplicationLocalUserSettingsDirectory(), + wmtsconnectioninfoConfigFile))) + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + var buttonAddLocation = new ButtonTester("addLocationButton", form); + + // When + buttonAddLocation.Click(); + + // Then + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(1, dataSource.Count); + var item = (WmtsConnectionInfo) comboBox.Items[0]; + Assert.AreEqual(name, item.Name); + Assert.AreEqual(url, item.Url); + + var connectToButton = (Button) new ButtonTester("connectToButton", form).TheObject; + Assert.IsTrue(connectToButton.Enabled); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndAddLocationClicked_WhenInValidDataInDialog_ThenWmtsLocationsNotUpdated() + { + // Given + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (var formTester = new FormTester(formName)) + { + var dialog = (WmtsConnectionDialog) formTester.TheObject; + var actionButtonTester = new ButtonTester("actionButton", dialog); + var actionButton = (Button) actionButtonTester.TheObject; + + actionButton.Enabled = true; + actionButtonTester.Click(); + } + }; + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + var buttonAddLocation = new ButtonTester("addLocationButton", form); + + // When + buttonAddLocation.Click(); + + // Then + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(0, dataSource.Count); + + var connectToButton = (Button) new ButtonTester("connectToButton", form).TheObject; + Assert.IsFalse(connectToButton.Enabled); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndAddLocationClicked_WhenConfigFileInUse_ThenWmtsLocationsNotUpdatedAndLogGenerated() + { + // Given + const string name = @"someName"; + const string url = @"someUrl"; + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(url)).Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (var formTester = new FormTester(formName)) + { + var dialog = (WmtsConnectionDialog) formTester.TheObject; + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", dialog).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", dialog).TheObject; + var actionButton = new ButtonTester("actionButton", dialog); + + nameTextBox.Text = name; + urlTextBox.Text = url; + + actionButton.Click(); + } + }; + + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + { + string configFilePath = Path.Combine(SettingsHelper.Instance.GetApplicationLocalUserSettingsDirectory(), + wmtsconnectioninfoConfigFile); + + using (var fileDisposeHelper = new FileDisposeHelper(configFilePath)) + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + fileDisposeHelper.LockFiles(); + + var buttonAddLocation = new ButtonTester("addLocationButton", form); + + // When + Action action = () => { buttonAddLocation.Click(); }; + + // Then + string exceptionMessage = $"Er is een onverwachte fout opgetreden tijdens het schrijven van het bestand '{configFilePath}'."; + TestHelper.AssertLogMessageWithLevelIsGenerated(action, Tuple.Create(exceptionMessage, LogLevelConstant.Error)); + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(1, dataSource.Count); + } + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndEditLocationClicked_WhenDialogCanceled_ThenWmtsLocationsNotUpdated() + { + // Given + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)) + .IgnoreArguments() + .Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (new FormTester(formName)) {} + }; + + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + comboBox.DataSource = new List + { + new WmtsConnectionInfo("oldName", "oldUrl") + }; + + var editLocationButton = new ButtonTester("editLocationButton", form); + ((Button) editLocationButton.TheObject).Enabled = true; + + // When + editLocationButton.Click(); + + // Then + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(1, dataSource.Count); + var item = (WmtsConnectionInfo) comboBox.Items[0]; + Assert.AreEqual("oldName", item.Name); + Assert.AreEqual("oldUrl", item.Url); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenWmtsLocationControlAndEditLocationClicked_WhenValidDataInDialog_ThenWmtsLocationsUpdated() + { + // Given + const string newName = @"newName"; + const string newUrl = @"newUrl"; + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities("oldUrl")).Return(Enumerable.Empty()); + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(newUrl)).Return(Enumerable.Empty()); + mockRepository.ReplayAll(); + + DialogBoxHandler = (formName, wnd) => + { + using (var formTester = new FormTester(formName)) + { + var dialog = (WmtsConnectionDialog) formTester.TheObject; + var nameTextBox = (TextBox) new TextBoxTester("nameTextBox", dialog).TheObject; + var urlTextBox = (TextBox) new TextBoxTester("urlTextBox", dialog).TheObject; + var actionButton = new ButtonTester("actionButton", dialog); + + nameTextBox.Text = newName; + urlTextBox.Text = newUrl; + + actionButton.Click(); + } + }; + + using (new UseCustomSettingsHelper(new TestSettingsHelper + { + ApplicationLocalUserSettingsDirectory = TestHelper.GetTestDataPath(testPath, "noConfig") + })) + using (new FileDisposeHelper(Path.Combine(SettingsHelper.Instance.GetApplicationLocalUserSettingsDirectory(), + wmtsconnectioninfoConfigFile))) + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + form.Controls.Add(control); + form.Show(); + + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + comboBox.DataSource = new List + { + new WmtsConnectionInfo("oldName", "oldUrl") + }; + + var editLocationButton = new ButtonTester("editLocationButton", form); + ((Button) editLocationButton.TheObject).Enabled = true; + + // When + editLocationButton.Click(); + + // Then + var dataSource = (List) comboBox.DataSource; + Assert.AreEqual(1, dataSource.Count); + var item = (WmtsConnectionInfo) comboBox.Items[0]; + Assert.AreEqual(newName, item.Name); + Assert.AreEqual(newUrl, item.Url); + } + } + + [Test] + public void GivenWmtsLocationControlAndConnectClicked_WhenValidDataFromUrl_ThenDataGridUpdated() + { + // Given + WmtsMapData backgroundMapData = WmtsMapData.CreateDefaultPdokMapData(); + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(backgroundMapData.SourceCapabilitiesUrl)) + .Return(new[] + { + CreateWmtsCapability(new TestWmtsTileSource(backgroundMapData)) + }).Repeat.Twice(); + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(backgroundMapData)) + using (var form = new Form()) + using (ShowValidWmtsLocationControl(form, wmtsCapabilityFactory)) + { + form.Show(); + var connectToButton = new ButtonTester("connectToButton", form); + + // When + connectToButton.Click(); + + // Then + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + DataGridViewRowCollection rows = dataGridViewControl.Rows; + Assert.AreEqual(1, rows.Count); + + DataGridViewCellCollection cells = rows[0].Cells; + Assert.AreEqual(4, cells.Count); + Assert.AreEqual("brtachtergrondkaart(EPSG:28992)", cells[mapLayerIdColumnIndex].FormattedValue); + Assert.AreEqual("image/png", cells[mapLayerFormatColumnIndex].FormattedValue); + Assert.AreEqual("Stub schema", cells[mapLayerTitleColumnIndex].FormattedValue); + Assert.AreEqual("EPSG:28992", cells[mapLayerCoordinateSystemColumnIndex].FormattedValue); + } + } + + [Test] + public void GivenWmtsLocationControlAndConnectClicked_WhenCannotFindTileSourceException_ThenErrorMessageShownAndLogGenerated() + { + // Given + const string exceptionMessage = "fail"; + + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)).IgnoreArguments().Return(Enumerable.Empty()); + wmtsCapabilityFactory.Expect(wcf => wcf.GetWmtsCapabilities(null)).IgnoreArguments().Throw(new CannotFindTileSourceException(exceptionMessage)); + mockRepository.ReplayAll(); + + string messageBoxTitle = null; + string messageBoxText = null; + DialogBoxHandler = (formName, wnd) => + { + var messageBox = new MessageBoxTester(wnd); + messageBoxTitle = messageBox.Title; + messageBoxText = messageBox.Text; + messageBox.ClickOk(); + }; + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + using (var form = new Form()) + using (ShowValidWmtsLocationControl(form, wmtsCapabilityFactory)) + { + form.Show(); + var connectToButton = new ButtonTester("connectToButton", form); + + // When + Action action = () => connectToButton.Click(); + + // Then + TestHelper.AssertLogMessageWithLevelIsGenerated(action, Tuple.Create(exceptionMessage, LogLevelConstant.Error)); + Assert.AreEqual("Fout", messageBoxTitle); + Assert.AreEqual(exceptionMessage, messageBoxText); + } + } + + [Test] + public void Dispose_DisposedAlreadyCalled_DoesNotThrowException() + { + // Setup + mockRepository.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(tileFactory)) + { + // Call + TestDelegate call = () => + { + using (var control = new WmtsLocationControl(null, wmtsCapabilityFactory)) + { + control.Dispose(); + } + }; + + // Assert + Assert.DoesNotThrow(call); + } + } + + private static WmtsCapability CreateWmtsCapability(TestWmtsTileSource tileSource) + { + var wmtsTileSchema = (WmtsTileSchema) tileSource.Schema; + return new WmtsCapability(wmtsTileSchema.Identifier, wmtsTileSchema.Format, + tileSource.Name, wmtsTileSchema.Srs); + } + + private static void AssertAreEqual(WmtsMapData expected, WmtsMapData actual) + { + if (expected == null) + { + Assert.IsNull(actual); + return; + } + Assert.AreEqual(expected.Name, actual.Name); + Assert.AreEqual(expected.PreferredFormat, actual.PreferredFormat); + Assert.AreEqual(expected.SelectedCapabilityIdentifier, actual.SelectedCapabilityIdentifier); + Assert.AreEqual(expected.SourceCapabilitiesUrl, actual.SourceCapabilitiesUrl); + } + + private static WmtsLocationControl ShowFullyConfiguredWmtsLocationControl(Form form, IWmtsCapabilityFactory wmtsCapabilityFactory) + { + WmtsLocationControl control = ShowValidWmtsLocationControl(form, wmtsCapabilityFactory); + + var capabilities = new List + { + new WmtsCapabilityRow(new WmtsCapability("-", "image/png", "-", "-")), + new WmtsCapabilityRow(new WmtsCapability("brtachtergrondkaart(EPSG:28992)", "image/png8", "brtachtergrondkaart", "EPSG:28992")) + }; + + var dataGridViewControl = (DataGridViewControl) new ControlTester("dataGridViewControl", form).TheObject; + dataGridViewControl.SetDataSource(capabilities); + + return control; + } + + private static WmtsLocationControl ShowValidWmtsLocationControl(Form form, IWmtsCapabilityFactory wmtsCapabilityFactory) + { + var control = new WmtsLocationControl(null, wmtsCapabilityFactory); + form.Controls.Add(control); + + var comboBox = (ComboBox) new ComboBoxTester("urlLocationComboBox", form).TheObject; + comboBox.DataSource = new List + { + new WmtsConnectionInfo("PDOK achtergrondkaart", "https://geodata.nationaalgeoregister.nl/wmts/top10nlv2?VERSION=1.0.0&request=GetCapabilities") + }; + + var connectToButton = (Button) new ButtonTester("connectToButton", form).TheObject; + connectToButton.Enabled = true; + return control; + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/WmtsCapabilityTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/WmtsCapabilityTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/WmtsCapabilityTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,184 @@ +// 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 Core.Common.TestUtil; +using Core.Components.Gis.Data; +using NUnit.Framework; + +namespace Core.Components.Gis.Forms.Test +{ + public class WmtsCapabilityTest + { + [Test] + public void Constructor_IdNull_ThrowsArgumentNullException() + { + // Setup + const string format = "image/png"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + + // Call + TestDelegate call = () => new WmtsCapability(null, format, title, coordinateSystem); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("id", paramName); + } + + [Test] + public void Constructor_FormatNull_ThrowsArgumentNullException() + { + // Setup + const string id = "laag1(abc)"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + + // Call + TestDelegate call = () => new WmtsCapability(id, null, title, coordinateSystem); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("format", paramName); + } + + [Test] + public void Constructor_TitleNull_ThrowsArgumentNullException() + { + // Setup + const string id = "laag1(abc)"; + const string format = "image/png"; + const string coordinateSystem = "Coördinatenstelsel"; + + // Call + TestDelegate call = () => new WmtsCapability(id, format, null, coordinateSystem); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("title", paramName); + } + + [Test] + public void Constructor_CoordinateSystemNull_ThrowsArgumentNullException() + { + // Setup + const string id = "laag1(abc)"; + const string format = "image/png"; + const string title = "Eerste kaartlaag"; + + // Call + TestDelegate call = () => new WmtsCapability(id, format, title, null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("coordinateSystem", paramName); + } + + [Test] + public void Constructor_FormatNotMIMEType_ThrowsArgumentException() + { + // Setup + const string id = "laag1(abc)"; + const string format = "some string"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + + // Call + TestDelegate call = () => new WmtsCapability(id, format, title, coordinateSystem); + + // Assert + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "Specified image format is not a MIME type."); + } + + [Test] + public void Constructor_ValidProperties_ExpectedProperties() + { + // Setup + const string id = "laag1(abc)"; + const string format = "image/png"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + + // Call + var wmtsCapability = new WmtsCapability(id, format, title, coordinateSystem); + + // Assert + Assert.AreEqual(id, wmtsCapability.Id); + Assert.AreEqual(format, wmtsCapability.Format); + Assert.AreEqual(title, wmtsCapability.Title); + Assert.AreEqual(coordinateSystem, wmtsCapability.CoordinateSystem); + } + + + [Test] + public void ToWmtsMapData_DisplayNameNull_ThrowsArgumentNullException() + { + // Setup + var wmtsCapability = new WmtsCapability("laag1(abc)", "image/png", "Eerste kaartlaag", "Coördinatenstelsel"); + const string sourceCapabilitiesUrl = "sourceCapabilitiesUrl"; + + // Call + TestDelegate call = () => wmtsCapability.ToWmtsMapdata(null, sourceCapabilitiesUrl); + + // Assert + Assert.Throws(call); + } + + [Test] + public void ToWmtsMapData_CapabilitiesUrlNull_ThrowsArgumentNullException() + { + // Setup + var wmtsCapability = new WmtsCapability("laag1(abc)", "image/png", "Eerste kaartlaag", "Coördinatenstelsel"); + const string displayName = "displayName"; + + // Call + TestDelegate call = () => wmtsCapability.ToWmtsMapdata(displayName, null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("sourceCapabilitiesUrl", paramName); + } + + [Test] + public void ToWmtsMapData_ValidParameters_ReturnsNewWmtsMapData() + { + // Setup + const string id = "laag1(abc)"; + const string format = "image/png"; + const string title = "Eerste kaartlaag"; + const string coordinateSystem = "Coördinatenstelsel"; + const string displayName = "displayName"; + const string sourceCapabilitiesUrl = "sourceCapabilitiesUrl"; + + var wmtsCapability = new WmtsCapability(id, format, title, coordinateSystem); + + // Call + WmtsMapData mapData = wmtsCapability.ToWmtsMapdata(displayName, sourceCapabilitiesUrl); + + // Assert + Assert.IsInstanceOf(mapData); + Assert.AreEqual(displayName, mapData.Name); + Assert.AreEqual(sourceCapabilitiesUrl, mapData.SourceCapabilitiesUrl); + } + + + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/app.config =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/app.config (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/app.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Forms.Test/packages.config =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Forms.Test/packages.config (revision 0) +++ Core/Components/test/Core.Components.Gis.Forms.Test/packages.config (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.IO.Test/Core.Components.Gis.IO.Test.csproj =================================================================== diff -u -r6a5d7b40b7ba4dcb73e393075338352d194e97c2 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.Gis.IO.Test/Core.Components.Gis.IO.Test.csproj (.../Core.Components.Gis.IO.Test.csproj) (revision 6a5d7b40b7ba4dcb73e393075338352d194e97c2) +++ Core/Components/test/Core.Components.Gis.IO.Test/Core.Components.Gis.IO.Test.csproj (.../Core.Components.Gis.IO.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -52,6 +52,7 @@ + @@ -63,9 +64,11 @@ + + Index: Core/Components/test/Core.Components.Gis.IO.Test/Readers/WmtsConnectionInfoReaderTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.IO.Test/Readers/WmtsConnectionInfoReaderTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.IO.Test/Readers/WmtsConnectionInfoReaderTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,261 @@ +// 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 System.Xml; +using Core.Common.IO.Exceptions; +using Core.Common.TestUtil; +using Core.Components.Gis.IO.Readers; +using NUnit.Framework; + +namespace Core.Components.Gis.IO.Test.Readers +{ + [TestFixture] + public class WmtsConnectionInfoReaderTest + { + private static readonly string testPath = TestHelper.GetTestDataPath(TestDataPath.Core.Components.DotSpatial.Forms, "WmtsConnectionInfo"); + + [Test] + [TestCase("")] + [TestCase(" ")] + [TestCase(null)] + public void ReadWmtsConnectionInfos_NoFilePath_ThrowArgumentException(string filePath) + { + // Setup + var reader = new WmtsConnectionInfoReader(); + + // Call + TestDelegate call = () => reader.ReadWmtsConnectionInfos(filePath); + + // Assert + const string expectedMessage = "bestandspad mag niet leeg of ongedefinieerd zijn."; + string message = Assert.Throws(call).Message; + StringAssert.Contains(expectedMessage, message); + } + + [Test] + public void ReadWmtsConnectionInfos_FilePathIsDirectory_ThrowArgumentException() + { + // Setup + var reader = new WmtsConnectionInfoReader(); + + // Call + TestDelegate call = () => reader.ReadWmtsConnectionInfos("c:/"); + + // Assert + const string expectedMessage = "bestandspad mag niet verwijzen naar een lege bestandsnaam."; + string message = Assert.Throws(call).Message; + StringAssert.Contains(expectedMessage, message); + } + + [Test] + public void ReadWmtsConnectionInfos_FilePathHasInvalidPathCharacter_ThrowArgumentException() + { + // Setup + char[] invalidPathChars = Path.GetInvalidPathChars(); + var filePath = "c:/_.config".Replace('_', invalidPathChars[0]); + var reader = new WmtsConnectionInfoReader(); + + // Call + TestDelegate call = () => reader.ReadWmtsConnectionInfos(filePath); + + // Assert + var expectedMessage = $"Fout bij het lezen van bestand '{filePath}': " + + "er zitten ongeldige tekens in het bestandspad. Alle tekens in het bestandspad moeten geldig zijn."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); + } + + [Test] + public void ReadWmtsConnectionInfos_FileMissing_ReturnsEmptyList() + { + // Setup + string filePath = Path.Combine(testPath, Path.GetRandomFileName()); + var reader = new WmtsConnectionInfoReader(); + + // Call + IEnumerable readInfos = reader.ReadWmtsConnectionInfos(filePath); + + // Assert + Assert.IsEmpty(readInfos); + } + + [Test] + public void ReadWmtsConnectionInfos_FileWithTwoWmtsConnectionInfos_ReturnsExpectedWmtsConnectionInfos() + { + // Setup + string filePath = Path.Combine(testPath, "twoValidWmtsConnectionInfos.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + WmtsConnectionInfo[] readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); + + // Assert + Assert.AreEqual(2, readConnectionInfos.Length); + var firstExpected = new WmtsConnectionInfo(@"Actueel Hoogtebestand Nederland (AHN1)", @"https://geodata.nationaalgeoregister.nl/tiles/service/wmts/ahn1?request=GetCapabilities"); + var secondExpected = new WmtsConnectionInfo(@"Zeegraskartering", @"https://geodata.nationaalgeoregister.nl/zeegraskartering/wfs?request=GetCapabilities"); + + AssertAreEqual(firstExpected, readConnectionInfos[0]); + AssertAreEqual(secondExpected, readConnectionInfos[1]); + } + + [Test] + public void ReadWmtsConnectionInfos_FileWithTwoWmtsConnectionInfosReversedOrder_ReturnsExpectedWmtsConnectionInfos() + { + // Setup + string filePath = Path.Combine(testPath, "twoValidWmtsConnectionInfosReversedOrder.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + WmtsConnectionInfo[] readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); + + // Assert + Assert.AreEqual(2, readConnectionInfos.Length); + var firstExpected = new WmtsConnectionInfo(@"Actueel Hoogtebestand Nederland (AHN1)", @"https://geodata.nationaalgeoregister.nl/tiles/service/wmts/ahn1?request=GetCapabilities"); + var secondExpected = new WmtsConnectionInfo(@"Zeegraskartering", @"https://geodata.nationaalgeoregister.nl/zeegraskartering/wfs?request=GetCapabilities"); + + AssertAreEqual(firstExpected, readConnectionInfos[0]); + AssertAreEqual(secondExpected, readConnectionInfos[1]); + } + + [Test] + public void ReadWmtsConnectionInfos_FileWithoutWmtsConnectionInfos_ReturnsEmptyList() + { + // Setup + string filePath = Path.Combine(testPath, "WmtsConnectionInfosZeroWmtsConnections.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + WmtsConnectionInfo[] readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); + + // Assert + Assert.AreEqual(0, readConnectionInfos.Length); + } + + [Test] + public void ReadWmtsConnectionInfos_FileWithoutWmtsConnectionsElement_ThrowsCriticalFileReadException() + { + // Setup + string filePath = Path.Combine(testPath, "WmtsConnectionInfosWithoutWmtsConnectionsElement.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + TestDelegate call = () => reader.ReadWmtsConnectionInfos(filePath); + + // Assert + var exception = Assert.Throws(call); + string expectedMessage = $"Fout bij het lezen van bestand '{filePath}': het bestand " + + "kon niet worden geopend. Mogelijk is het bestand corrupt " + + "of in gebruik door een andere applicatie."; + Assert.AreEqual(expectedMessage, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + + [Test] + public void ReadWmtsConnectionInfos_FileEmptyUrlElement_WarnsAndReadsRestOfFile() + { + // Setup + string filePath = Path.Combine(testPath, "twoWmtsConnectionInfosOneEmptyUrl.txt"); + var reader = new WmtsConnectionInfoReader(); + + WmtsConnectionInfo[] readConnectionInfos = null; + + // Call + Action action = () => { readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); }; + + // Assert + string expectedMessage = $"Fout bij het lezen van bestand '{filePath}': het is niet mogelijk om WMTS connectie 'First name' aan te maken met URL ''."; + TestHelper.AssertLogMessageWithLevelIsGenerated(action, Tuple.Create(expectedMessage, LogLevelConstant.Warn)); + + Assert.IsNotNull(readConnectionInfos); + Assert.AreEqual(1, readConnectionInfos.Length); + var expectedWmtsConnectionInfo = new WmtsConnectionInfo(@"second name", @"https://domain.com"); + + AssertAreEqual(expectedWmtsConnectionInfo, readConnectionInfos[0]); + } + + [Test] + public void ReadWmtsConnectionInfos_FileMissingOneUrlElement_SkipdAndReadsRestOfFile() + { + // Setup + string filePath = Path.Combine(testPath, "twoWmtsConnectionInfosOneWithoutUrlElement.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + WmtsConnectionInfo[] readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); + + // Assert + Assert.AreEqual(1, readConnectionInfos.Length); + var expectedWmtsConnectionInfo = new WmtsConnectionInfo(@"second name", @"https://domain.com"); + + AssertAreEqual(expectedWmtsConnectionInfo, readConnectionInfos[0]); + } + + [Test] + public void ReadWmtsConnectionInfos_FileMissingOneNameElement_SkipdAndReadsRestOfFile() + { + // Setup + string filePath = Path.Combine(testPath, "twoWmtsConnectionInfosOneWithoutNameElement.txt"); + var reader = new WmtsConnectionInfoReader(); + + // Call + WmtsConnectionInfo[] readConnectionInfos = reader.ReadWmtsConnectionInfos(filePath).ToArray(); + + // Assert + Assert.AreEqual(1, readConnectionInfos.Length); + var expectedWmtsConnectionInfo = new WmtsConnectionInfo(@"second name", @"https://domain.com"); + + AssertAreEqual(expectedWmtsConnectionInfo, readConnectionInfos[0]); + } + + [Test] + public void ReadWmtsConnectionInfos_FileLocked_ThrowsCriticalFileReadException() + { + // Setup + string filePath = TestHelper.GetScratchPadPath(nameof(ReadWmtsConnectionInfos_FileLocked_ThrowsCriticalFileReadException)); + var reader = new WmtsConnectionInfoReader(); + + using (var fileDisposeHelper = new FileDisposeHelper(filePath)) + { + fileDisposeHelper.LockFiles(); + + // Call + TestDelegate call = () => reader.ReadWmtsConnectionInfos(filePath); + + // Assert + var exception = Assert.Throws(call); + string expectedMessage = $"Fout bij het lezen van bestand '{filePath}': het bestand " + + "kon niet worden geopend. Mogelijk is het bestand corrupt " + + "of in gebruik door een andere applicatie."; + Assert.AreEqual(expectedMessage, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + } + + private static void AssertAreEqual(WmtsConnectionInfo expected, WmtsConnectionInfo actual) + { + Assert.AreEqual(expected.Name, actual.Name); + Assert.AreEqual(expected.Url, actual.Url); + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.IO.Test/Writers/WmtsConnectionInfoWriterTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.IO.Test/Writers/WmtsConnectionInfoWriterTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.IO.Test/Writers/WmtsConnectionInfoWriterTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,180 @@ +// 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.IO; +using System.Linq; +using System.Security.AccessControl; +using Core.Common.IO.Exceptions; +using Core.Common.TestUtil; +using Core.Components.Gis.IO.Writers; +using NUnit.Framework; + +namespace Core.Components.Gis.IO.Test.Writers +{ + [TestFixture] + public class WmtsConnectionInfoWriterTest + { + [Test] + [TestCase("")] + [TestCase(" ")] + [TestCase(null)] + public void Constructor_NoFilePath_ThrowArgumentException(string filePath) + { + // Call + TestDelegate call = () => new WmtsConnectionInfoWriter(filePath); + + // Assert + const string expectedMessage = "bestandspad mag niet leeg of ongedefinieerd zijn."; + string message = Assert.Throws(call).Message; + StringAssert.Contains(expectedMessage, message); + } + + [Test] + public void Constructor_FilePathIsDirectory_ThrowArgumentException() + { + // Call + TestDelegate call = () => new WmtsConnectionInfoWriter("c:/"); + + // Assert + const string expectedMessage = "bestandspad mag niet verwijzen naar een lege bestandsnaam."; + string message = Assert.Throws(call).Message; + StringAssert.Contains(expectedMessage, message); + } + + [Test] + public void Constructor_FilePathHasInvalidPathCharacter_ThrowArgumentException() + { + // Setup + char[] invalidPathChars = Path.GetInvalidPathChars(); + var filePath = "c:/_.config".Replace('_', invalidPathChars[0]); + + // Call + TestDelegate call = () => new WmtsConnectionInfoWriter(filePath); + + // Assert + var expectedMessage = $"Fout bij het lezen van bestand '{filePath}': " + + "er zitten ongeldige tekens in het bestandspad. Alle tekens in het bestandspad moeten geldig zijn."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); + } + + [Test] + public void WriteWmtsConnectionInfo_DirectoryDoesNotExist_CreatesDirectoryAndFile() + { + // Setup + string directoryPath = TestHelper.GetScratchPadPath(nameof(WriteWmtsConnectionInfo_DirectoryDoesNotExist_CreatesDirectoryAndFile)); + string filePath = Path.Combine(directoryPath, Path.GetRandomFileName()); + var wmtsConfigurationWriter = new WmtsConnectionInfoWriter(filePath); + + try + { + // Call + wmtsConfigurationWriter.WriteWmtsConnectionInfo(Enumerable.Empty()); + + // Assert + Assert.IsTrue(File.Exists(filePath)); + } + finally + { + Directory.Delete(directoryPath, true); + } + } + + [Test] + public void WriteWmtsConnectionInfo_InvalidDirectoryRights_ThrowCriticalFileWriteException() + { + // Setup + string directoryPath = TestHelper.GetScratchPadPath(nameof(WriteWmtsConnectionInfo_InvalidDirectoryRights_ThrowCriticalFileWriteException)); + Directory.CreateDirectory(directoryPath); + string filePath = Path.Combine(directoryPath, Path.GetRandomFileName()); + var wmtsConfigurationWriter = new WmtsConnectionInfoWriter(filePath); + + try + { + using (new DirectoryPermissionsRevoker(directoryPath, FileSystemRights.Write)) + { + // Call + TestDelegate call = () => wmtsConfigurationWriter.WriteWmtsConnectionInfo(Enumerable.Empty()); + + // Assert + string message = Assert.Throws(call).Message; + var expectedMessage = $"Er is een onverwachte fout opgetreden tijdens het schrijven van het bestand '{filePath}'."; + Assert.AreEqual(expectedMessage, message); + } + } + finally + { + Directory.Delete(directoryPath, true); + } + } + + [Test] + public void WriteWmtsConnectionInfo_WmtsConnectionInfosNull_ThrowArgumentNullException() + { + // Setup + string filePath = TestHelper.GetScratchPadPath(nameof(WriteWmtsConnectionInfo_WmtsConnectionInfosNull_ThrowArgumentNullException)); + var wmtsConfigurationWriter = new WmtsConnectionInfoWriter(filePath); + + // Call + TestDelegate call = () => wmtsConfigurationWriter.WriteWmtsConnectionInfo(null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("wmtsConnectionInfos", paramName); + } + + [Test] + public void WriteWmtsConnectionInfo_ValidWmtsConnectionInfo_SavesWmtsConnectionInfoToFile() + { + // Setup + string filePath = TestHelper.GetScratchPadPath(nameof(WriteWmtsConnectionInfo_ValidWmtsConnectionInfo_SavesWmtsConnectionInfoToFile)); + var wmtsConfigurationWriter = new WmtsConnectionInfoWriter(filePath); + + var wmtsConnectionInfos = new[] + { + new WmtsConnectionInfo("name1", "url1"), + new WmtsConnectionInfo("name2", "url2") + }; + + using (new FileDisposeHelper(filePath)) + { + // Call + wmtsConfigurationWriter.WriteWmtsConnectionInfo(wmtsConnectionInfos); + + // Assert + string actualContent = GetFileContent(filePath); + string expectedContent = "" + + "name1url1" + + "name2url2" + + ""; + Assert.AreEqual(expectedContent, actualContent); + } + } + + private static string GetFileContent(string filePath) + { + using (var reader = new StreamReader(filePath)) + { + return reader.ReadToEnd(); + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Test/Core.Components.Gis.Test.csproj =================================================================== diff -u -r31012b85637f7fcf6b28f498fc996edcda2eb505 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Core/Components/test/Core.Components.Gis.Test/Core.Components.Gis.Test.csproj (.../Core.Components.Gis.Test.csproj) (revision 31012b85637f7fcf6b28f498fc996edcda2eb505) +++ Core/Components/test/Core.Components.Gis.Test/Core.Components.Gis.Test.csproj (.../Core.Components.Gis.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -62,12 +62,16 @@ + + + + Index: Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotCreateTileCacheExceptionTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotCreateTileCacheExceptionTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotCreateTileCacheExceptionTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,32 @@ +// 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 Core.Common.TestUtil; +using Core.Components.Gis.Exceptions; +using NUnit.Framework; + +namespace Core.Components.Gis.Test.Exceptions +{ + [TestFixture] + public class CannotCreateTileCacheExceptionTest : + CustomExceptionDesignGuidelinesTestFixture {} +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotFindTileSourceExceptionTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotFindTileSourceExceptionTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotFindTileSourceExceptionTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,32 @@ +// 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 Core.Common.TestUtil; +using Core.Components.Gis.Exceptions; +using NUnit.Framework; + +namespace Core.Components.Gis.Test.Exceptions +{ + [TestFixture] + public class CannotFindTileSourceExceptionTest : + CustomExceptionDesignGuidelinesTestFixture {} +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotReceiveTilesExceptionTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotReceiveTilesExceptionTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Test/Exceptions/CannotReceiveTilesExceptionTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,32 @@ +// 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 Core.Common.TestUtil; +using Core.Components.Gis.Exceptions; +using NUnit.Framework; + +namespace Core.Components.Gis.Test.Exceptions +{ + [TestFixture] + public class CannotReceiveTilesExceptionTest : + CustomExceptionDesignGuidelinesTestFixture {} +} \ No newline at end of file Index: Core/Components/test/Core.Components.Gis.Test/WmtsConnectionInfoTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.Gis.Test/WmtsConnectionInfoTest.cs (revision 0) +++ Core/Components/test/Core.Components.Gis.Test/WmtsConnectionInfoTest.cs (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -0,0 +1,172 @@ +// 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 Core.Common.TestUtil; +using NUnit.Framework; + +namespace Core.Components.Gis.Test +{ + [TestFixture] + public class WmtsConnectionInfoTest + { + [Test] + public void Constructor_NameNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => new WmtsConnectionInfo(null, "url"); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("name", paramName); + } + + [Test] + public void Constructor_UrlNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => new WmtsConnectionInfo("name", null); + + // Assert + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "url must have a value."); + } + + [Test] + public void Constructor_ValidParameters_ExpectedProperties() + { + // Setup + const string name = "name"; + const string url = "url"; + + // Call + var connectionInfo = new WmtsConnectionInfo(name, url); + + // Assert + Assert.AreEqual(name, connectionInfo.Name); + Assert.AreEqual(url, connectionInfo.Url); + } + + [Test] + public void Equals_ToNull_ReturnFalse() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + + // Call + var isEqual = info.Equals(null); + + // Assert + Assert.IsFalse(isEqual); + } + + [Test] + public void Equals_ToOtherObject_ReturnFalse() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + + // Call + var isEqual = info.Equals(new object()); + + // Assert + Assert.IsFalse(isEqual); + } + + [Test] + public void Equals_ToItself_ReturnTrue() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + + // Call + var isEqual = info.Equals(info); + + // Assert + Assert.IsTrue(isEqual); + } + + [Test] + public void Equals_ToOtherWithSameNameDifferentUrl_ReturnsFalse() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + var other = new WmtsConnectionInfo("name", "otherUrl"); + + // Call + var isEqual = info.Equals(other); + var otherIsEqual = info.Equals(other); + + // Assert + Assert.IsFalse(isEqual); + Assert.IsFalse(otherIsEqual); + } + + [Test] + public void Equals_ToOtherWithDifferentNameSameUrl_ReturnsFalse() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + var other = new WmtsConnectionInfo("otherName", "url"); + + // Call + var isEqual = info.Equals(other); + var otherIsEqual = info.Equals(other); + + // Assert + Assert.IsFalse(isEqual); + Assert.IsFalse(otherIsEqual); + } + + [Test] + public void Equals_ToOtherWithSameData_ReturnsTrue() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + var other = new WmtsConnectionInfo("name", "url"); + + // Call + var isEqual = info.Equals(other); + var otherIsEqual = info.Equals(other); + + // Assert + Assert.IsTrue(isEqual); + Assert.IsTrue(otherIsEqual); + } + + [Test] + public void GetHashCode_EqualObjects_ReturnSameHashCode() + { + // Setup + var info = new WmtsConnectionInfo("name", "url"); + var other = new WmtsConnectionInfo("name", "url"); + + // Precondition + Assert.AreEqual(info, other); + + // Call + int hashCode = info.GetHashCode(); + int otherHashCode = other.GetHashCode(); + + // Assert + Assert.AreEqual(hashCode, otherHashCode); + } + } +} \ No newline at end of file Index: Ringtoets.sln =================================================================== diff -u -r661cb6041b3d518ad5e38848326eae975eb6a695 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets.sln (.../Ringtoets.sln) (revision 661cb6041b3d518ad5e38848326eae975eb6a695) +++ Ringtoets.sln (.../Ringtoets.sln) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -91,6 +91,7 @@ {D63FCFEC-34E8-4C68-8B4F-99338D2447AC} = {D63FCFEC-34E8-4C68-8B4F-99338D2447AC} {83A782F1-BA78-4D5C-B213-39066605AFD8} = {83A782F1-BA78-4D5C-B213-39066605AFD8} {22E191F2-B2E3-413C-9511-4C2CDEDB2EFF} = {22E191F2-B2E3-413C-9511-4C2CDEDB2EFF} + {3DCEF8F6-CB6D-435C-9539-50143DACD86C} = {3DCEF8F6-CB6D-435C-9539-50143DACD86C} {66DD5FFB-EE06-40F2-9260-01F26D6FD1B4} = {66DD5FFB-EE06-40F2-9260-01F26D6FD1B4} EndProjectSection EndProject @@ -1428,6 +1429,31 @@ {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Components.BruTile.Data", "Core\Components\src\Core.Components.BruTile.Data\Core.Components.BruTile.Data.csproj", "{3DCEF8F6-CB6D-435C-9539-50143DACD86C}" + ProjectSection(ProjectDependencies) = postProject + {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Components.BruTile.Data.Test", "Core\Components\test\Core.Components.BruTile.Data.Test\Core.Components.BruTile.Data.Test.csproj", "{18DC8B68-59FB-4246-A9B0-2321D4627E10}" + ProjectSection(ProjectDependencies) = postProject + {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Components.BruTile.TestUtil", "Core\Components\test\Core.Components.BruTile.TestUtil\Core.Components.BruTile.TestUtil.csproj", "{1081336C-D919-4249-AB33-9AF15F4D19EC}" + ProjectSection(ProjectDependencies) = postProject + {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Components.BruTile.TestUtil.Test", "Core\Components\test\Core.Components.BruTile.TestUtil.Test\Core.Components.BruTile.TestUtil.Test.csproj", "{69B97F30-F52B-4A31-A250-7280123CFF3D}" + ProjectSection(ProjectDependencies) = postProject + {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Components.Gis.Forms.Test", "Core\Components\test\Core.Components.GIS.Forms.Test\Core.Components.Gis.Forms.Test.csproj", "{FC8F3315-E129-44AD-8A0E-F7979094EE4C}" + ProjectSection(ProjectDependencies) = postProject + {C90B77DA-E421-43CC-B82E-529651BC21AC} = {C90B77DA-E421-43CC-B82E-529651BC21AC} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CreateInstaller|x86 = CreateInstaller|x86 @@ -3585,6 +3611,48 @@ {041095A1-5C95-482E-A063-9A4796E4DA38}.Release|x86.Build.0 = Release|x86 {041095A1-5C95-482E-A063-9A4796E4DA38}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 {041095A1-5C95-482E-A063-9A4796E4DA38}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.CreateInstaller|x86.ActiveCfg = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.CreateInstaller|x86.Build.0 = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.CreateInstallerWithDemoProject|x86.ActiveCfg = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.CreateInstallerWithDemoProject|x86.Build.0 = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.Debug|x86.ActiveCfg = Debug|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.Debug|x86.Build.0 = Debug|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.Release|x86.ActiveCfg = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.Release|x86.Build.0 = Release|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 + {3DCEF8F6-CB6D-435C-9539-50143DACD86C}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.CreateInstaller|x86.ActiveCfg = Release|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.CreateInstallerWithDemoProject|x86.ActiveCfg = Release|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.Debug|x86.ActiveCfg = Debug|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.Debug|x86.Build.0 = Debug|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.Release|x86.ActiveCfg = Release|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.Release|x86.Build.0 = Release|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 + {18DC8B68-59FB-4246-A9B0-2321D4627E10}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.CreateInstaller|x86.ActiveCfg = Release|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.CreateInstallerWithDemoProject|x86.ActiveCfg = Release|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.Debug|x86.ActiveCfg = Debug|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.Debug|x86.Build.0 = Debug|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.Release|x86.ActiveCfg = Release|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.Release|x86.Build.0 = Release|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 + {1081336C-D919-4249-AB33-9AF15F4D19EC}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.CreateInstaller|x86.ActiveCfg = Release|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.CreateInstallerWithDemoProject|x86.ActiveCfg = Release|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.Debug|x86.ActiveCfg = Debug|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.Debug|x86.Build.0 = Debug|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.Release|x86.ActiveCfg = Release|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.Release|x86.Build.0 = Release|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 + {69B97F30-F52B-4A31-A250-7280123CFF3D}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.CreateInstaller|x86.ActiveCfg = Release|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.CreateInstallerWithDemoProject|x86.ActiveCfg = Release|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.Debug|x86.ActiveCfg = Debug|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.Debug|x86.Build.0 = Debug|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.Release|x86.ActiveCfg = Release|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.Release|x86.Build.0 = Release|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.ReleaseForCodeCoverage|x86.ActiveCfg = ReleaseForCodeCoverage|x86 + {FC8F3315-E129-44AD-8A0E-F7979094EE4C}.ReleaseForCodeCoverage|x86.Build.0 = ReleaseForCodeCoverage|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3898,6 +3966,11 @@ {0CE93555-A056-434C-9D91-B55DBA7C3877} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} {05A2A229-B98A-43F5-8F86-B812F30CAF5B} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} {041095A1-5C95-482E-A063-9A4796E4DA38} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} + {3DCEF8F6-CB6D-435C-9539-50143DACD86C} = {7A696ACF-BA09-41A2-A912-A26E82C494CF} + {18DC8B68-59FB-4246-A9B0-2321D4627E10} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} + {1081336C-D919-4249-AB33-9AF15F4D19EC} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} + {69B97F30-F52B-4A31-A250-7280123CFF3D} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} + {FC8F3315-E129-44AD-8A0E-F7979094EE4C} = {D9DC93FF-DCF3-44A4-9193-9911966CDFF4} EndGlobalSection GlobalSection(TextTemplating) = postSolution TextTemplating = 1 Index: Ringtoets/Integration/src/Ringtoets.Integration.Forms/BackgroundMapDataSelectionDialog.cs =================================================================== diff -u -r1de256e81f3fa2c070810593152e87ad6affab97 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Integration/src/Ringtoets.Integration.Forms/BackgroundMapDataSelectionDialog.cs (.../BackgroundMapDataSelectionDialog.cs) (revision 1de256e81f3fa2c070810593152e87ad6affab97) +++ Ringtoets/Integration/src/Ringtoets.Integration.Forms/BackgroundMapDataSelectionDialog.cs (.../BackgroundMapDataSelectionDialog.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -24,8 +24,9 @@ using System.Linq; using System.Windows.Forms; using Core.Common.Controls.Dialogs; -using Core.Components.DotSpatial.Forms.Views; +using Core.Components.BruTile.Forms; using Core.Components.Gis.Data; +using Core.Components.Gis.Forms.Views; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; namespace Ringtoets.Integration.Forms @@ -50,7 +51,7 @@ { mapDatas = new List { - new WmtsLocationControl(mapData) + new WmtsLocationControl(mapData, new BruTileWmtsCapabilityFactory()) }; SelectedMapData = mapData; Index: Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundMapDataContainerProperties.cs =================================================================== diff -u -r4d42665303ba643c7dde86a0e8771c95821dbcf7 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundMapDataContainerProperties.cs (.../BackgroundMapDataContainerProperties.cs) (revision 4d42665303ba643c7dde86a0e8771c95821dbcf7) +++ Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundMapDataContainerProperties.cs (.../BackgroundMapDataContainerProperties.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -30,7 +30,7 @@ using Core.Components.Gis.Data; using Ringtoets.Integration.Forms.Properties; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; -using DotSpatialFormsResources = Core.Components.DotSpatial.Forms.Properties.Resources; +using GisFormsResources = Core.Components.Gis.Forms.Properties.Resources; namespace Ringtoets.Integration.Forms.PropertyClasses { @@ -125,7 +125,7 @@ [DynamicVisible] [ResourcesCategory(typeof(Resources), nameof(Resources.BackgroundWmtsMapDataContainerProperties_WMTS_Category))] - [ResourcesDisplayName(typeof(DotSpatialFormsResources), nameof(DotSpatialFormsResources.WmtsCapability_MapLayer_Id))] + [ResourcesDisplayName(typeof(GisFormsResources), nameof(GisFormsResources.WmtsCapability_MapLayer_Id))] [ResourcesDescription(typeof(Resources), nameof(Resources.BackgroundWmtsMapDataContainerProperties_SelectedCapabilityIdentifier_Description))] public string SelectedCapabilityIdentifier { @@ -137,7 +137,7 @@ [DynamicVisible] [ResourcesCategory(typeof(Resources), nameof(Resources.BackgroundWmtsMapDataContainerProperties_WMTS_Category))] - [ResourcesDisplayName(typeof(DotSpatialFormsResources), nameof(DotSpatialFormsResources.WmtsCapability_MapLayer_Format))] + [ResourcesDisplayName(typeof(GisFormsResources), nameof(GisFormsResources.WmtsCapability_MapLayer_Format))] [ResourcesDescription(typeof(Resources), nameof(Resources.BackgroundWmtsMapDataContainerProperties_PreferredFormat_Description))] public string PreferredFormat { Index: Ringtoets/Integration/src/Ringtoets.Integration.Forms/Ringtoets.Integration.Forms.csproj =================================================================== diff -u -r2ecb6f0551396f53cdb041e6b77275084d097ab7 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Integration/src/Ringtoets.Integration.Forms/Ringtoets.Integration.Forms.csproj (.../Ringtoets.Integration.Forms.csproj) (revision 2ecb6f0551396f53cdb041e6b77275084d097ab7) +++ Ringtoets/Integration/src/Ringtoets.Integration.Forms/Ringtoets.Integration.Forms.csproj (.../Ringtoets.Integration.Forms.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -176,6 +176,11 @@ Core.Common.Utils False + + {1BA9EBD0-AA64-4BE3-9791-B2EE344EC938} + Core.Components.BruTile.Forms + False + {5A91174A-FB95-4C9D-9CA5-81C0B8D4361A} Core.Components.DotSpatial.Forms Index: Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/BackgroundMapDataSelectionDialogTest.cs =================================================================== diff -u -r8ed20afbbecb8d353372e6623e7bbf68cdee543c -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/BackgroundMapDataSelectionDialogTest.cs (.../BackgroundMapDataSelectionDialogTest.cs) (revision 8ed20afbbecb8d353372e6623e7bbf68cdee543c) +++ Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/BackgroundMapDataSelectionDialogTest.cs (.../BackgroundMapDataSelectionDialogTest.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -28,10 +28,10 @@ using BruTile; using Core.Common.Controls.Dialogs; using Core.Common.TestUtil; -using Core.Components.DotSpatial.Forms.Views; -using Core.Components.DotSpatial.Layer.BruTile.Configurations; -using Core.Components.DotSpatial.TestUtil; +using Core.Components.BruTile.Configurations; +using Core.Components.BruTile.TestUtil; using Core.Components.Gis.Data; +using Core.Components.Gis.Forms.Views; using NUnit.Extensions.Forms; using NUnit.Framework; using Rhino.Mocks; Index: Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/Ringtoets.Integration.Forms.Test.csproj =================================================================== diff -u -rae74507edbfc4fe632ba5f964a147aff630dfe6e -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/Ringtoets.Integration.Forms.Test.csproj (.../Ringtoets.Integration.Forms.Test.csproj) (revision ae74507edbfc4fe632ba5f964a147aff630dfe6e) +++ Ringtoets/Integration/test/Ringtoets.Integration.Forms.Test/Ringtoets.Integration.Forms.Test.csproj (.../Ringtoets.Integration.Forms.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -141,6 +141,10 @@ {d749ee4c-ce50-4c17-bf01-9a953028c126} Core.Common.TestUtil + + {E02482C7-F12B-42F0-BB2B-C7EC17503A72} + Core.Components.BruTile + {5A91174A-FB95-4C9D-9CA5-81C0B8D4361A} Core.Components.DotSpatial.Forms @@ -157,6 +161,10 @@ {318ba582-88c9-4816-a54a-a7e431461de3} Core.Components.Gis + + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Core.Components.BruTile.TestUtil + {9B6F3987-EAF7-4733-80C1-3DCAB44D87AE} Core.Components.DotSpatial.TestUtil Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Ringtoets.Piping.Forms.Test.csproj =================================================================== diff -u -rb0f0dfdfde23bd325abaf66af82e570d4df5f391 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Ringtoets.Piping.Forms.Test.csproj (.../Ringtoets.Piping.Forms.Test.csproj) (revision b0f0dfdfde23bd325abaf66af82e570d4df5f391) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Ringtoets.Piping.Forms.Test.csproj (.../Ringtoets.Piping.Forms.Test.csproj) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -123,6 +123,10 @@ {d749ee4c-ce50-4c17-bf01-9a953028c126} Core.Common.TestUtil + + {e02482c7-f12b-42f0-bb2b-c7ec17503a72} + Core.Components.BruTile + {2465CCA1-C505-4827-9454-4FD5FD9194CD} Core.Components.Charting.Forms @@ -147,6 +151,10 @@ {318ba582-88c9-4816-a54a-a7e431461de3} Core.Components.Gis + + {1081336C-D919-4249-AB33-9AF15F4D19EC} + Core.Components.BruTile.TestUtil + {9b6f3987-eaf7-4733-80c1-3dcab44d87ae} Core.Components.DotSpatial.TestUtil Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingFailureMechanismViewTest.cs =================================================================== diff -u -r31012b85637f7fcf6b28f498fc996edcda2eb505 -r99f9004206bfb9de084275d749b7aeccafd6da18 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingFailureMechanismViewTest.cs (.../PipingFailureMechanismViewTest.cs) (revision 31012b85637f7fcf6b28f498fc996edcda2eb505) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingFailureMechanismViewTest.cs (.../PipingFailureMechanismViewTest.cs) (revision 99f9004206bfb9de084275d749b7aeccafd6da18) @@ -24,6 +24,7 @@ using System.Linq; using System.Windows.Forms; using Core.Common.Base.Geometry; +using Core.Components.BruTile.TestUtil; using Core.Components.DotSpatial.Forms; using Core.Components.DotSpatial.TestUtil; using Core.Components.Gis.Data;