// Copyright (C) Stichting Deltares and State of the Netherlands 2024. All rights reserved.
//
// This file is part of Riskeer.
//
// Riskeer 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.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Core.Common.Base.Geometry;
using Core.Components.DotSpatial.Converter;
using Core.Components.Gis.Data;
using Core.Components.Gis.Features;
using Core.Components.Gis.Geometries;
using Core.Components.Gis.Style;
using Core.Components.Gis.TestUtil;
using Core.Components.Gis.Theme;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
using NUnit.Framework;
using Rhino.Mocks;
namespace Core.Components.DotSpatial.Test.Converter
{
[TestFixture]
public class MapLineDataConverterTest
{
[Test]
public void DefaultConstructor_IsMapLineDataConverter()
{
// Call
var converter = new MapLineDataConverter();
// Assert
Assert.IsInstanceOf>(converter);
}
[Test]
public void ConvertLayerFeatures_MapLineDataWithMultipleFeatures_ConvertsAllFeaturesToMapLineLayer()
{
// Setup
var converter = new MapLineDataConverter();
var mapLineLayer = new MapLineLayer();
var mapLineData = new MapLineData("test")
{
Features = new[]
{
new MapFeature(Enumerable.Empty()),
new MapFeature(Enumerable.Empty()),
new MapFeature(Enumerable.Empty())
}
};
// Call
converter.ConvertLayerFeatures(mapLineData, mapLineLayer);
// Assert
Assert.AreEqual(mapLineData.Features.Count(), mapLineLayer.DataSet.Features.Count);
}
[Test]
public void ConvertLayerFeatures_MapLineDataWithSingleGeometryFeature_ConvertsFeaturesToMapLineLayerAsLineStringData()
{
// Setup
var converter = new MapLineDataConverter();
var mapLineLayer = new MapLineLayer();
var random = new Random(21);
var mapFeature = new MapFeature(new[]
{
new MapGeometry(new[]
{
new[]
{
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble())
}
})
});
var mapLineData = new MapLineData("test data")
{
Features = new[]
{
mapFeature
}
};
// Call
converter.ConvertLayerFeatures(mapLineData, mapLineLayer);
// Assert
IFeature feature = mapLineLayer.DataSet.Features[0];
Assert.AreEqual(mapLineData.Features.Count(), mapLineLayer.DataSet.Features.Count);
Assert.IsInstanceOf(feature.Geometry);
IEnumerable expectedCoordinates = mapFeature.MapGeometries.ElementAt(0).PointCollections.ElementAt(0)
.Select(p => new Coordinate(p.X, p.Y));
CollectionAssert.AreEqual(expectedCoordinates, feature.Geometry.Coordinates);
}
[Test]
public void ConvertLayerFeatures_MapLineDataWithMultipleGeometryFeature_ConvertsFeaturesToMapLineLayerAsMultiLineStringData()
{
// Setup
var converter = new MapLineDataConverter();
var mapLineLayer = new MapLineLayer();
var random = new Random(21);
var mapFeature = new MapFeature(new[]
{
new MapGeometry(new[]
{
new[]
{
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble())
}
}),
new MapGeometry(new[]
{
new[]
{
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble())
}
})
});
var mapLineData = new MapLineData("test data")
{
Features = new[]
{
mapFeature
}
};
// Call
converter.ConvertLayerFeatures(mapLineData, mapLineLayer);
// Assert
IFeature feature = mapLineLayer.DataSet.Features[0];
Assert.AreEqual(mapLineData.Features.Count(), mapLineLayer.DataSet.Features.Count);
Assert.IsInstanceOf(feature.Geometry);
IEnumerable expectedCoordinates = mapFeature.MapGeometries.SelectMany(mg => mg.PointCollections.ElementAt(0).Select(p => new Coordinate(p.X, p.Y)));
CollectionAssert.AreEqual(expectedCoordinates, feature.Geometry.Coordinates);
}
[Test]
public void GivenMapLayerWithScheme_WhenConvertingLayerFeatures_ThenClearsAppliedSchemeAndAppliesDefaultCategory()
{
// Given
var mocks = new MockRepository();
var categoryOne = mocks.Stub();
var categoryTwo = mocks.Stub();
mocks.ReplayAll();
var mapLineLayer = new MapLineLayer
{
Symbology = new LineScheme
{
Categories =
{
categoryOne,
categoryTwo
}
}
};
var converter = new MapLineDataConverter();
var random = new Random(21);
var lineStyle = new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
};
var theme = new MapTheme("Meta", new[]
{
new LineCategoryTheme(ValueCriterionTestFactory.CreateValueCriterion(),
new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
})
});
var mapLineData = new MapLineData("test", lineStyle, theme)
{
Features = new[]
{
CreateMapFeatureWithMetaData("Meta")
}
};
// When
converter.ConvertLayerFeatures(mapLineData, mapLineLayer);
// Then
LineCategoryCollection categoryCollection = mapLineLayer.Symbology.Categories;
Assert.AreEqual(1, categoryCollection.Count);
ILineSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(lineStyle);
AssertAreEqual(expectedSymbolizer, categoryCollection.Single().Symbolizer);
mocks.VerifyAll();
}
[Test]
[Combinatorial]
public void ConvertLayerProperties_MapLineDataWithStyle_ConvertsStyleToMapLineLayer(
[Values(KnownColor.AliceBlue, KnownColor.Azure)]
KnownColor color,
[Values(1, 5)] int width,
[Values(LineDashStyle.Solid, LineDashStyle.Dash)]
LineDashStyle lineStyle)
{
// Setup
Color expectedColor = Color.FromKnownColor(color);
var converter = new MapLineDataConverter();
var mapLineLayer = new MapLineLayer();
var mapLineData = new MapLineData("test", new LineStyle
{
Color = expectedColor,
Width = width,
DashStyle = lineStyle
});
// Call
converter.ConvertLayerProperties(mapLineData, mapLineLayer);
// Assert
AssertAreEqual(new LineSymbolizer(expectedColor, expectedColor, width, MapDataHelper.Convert(lineStyle), LineCap.Round), mapLineLayer.Symbolizer);
}
[Test]
public void ConvertLayerProperties_MapLineDataWithThemeAndMetaDataNameNotInFeatures_OnlyAddsDefaultCategory()
{
// Setup
const string metadataAttribute = "Meta";
var random = new Random(21);
var theme = new MapTheme("Other Meta", new[]
{
new LineCategoryTheme(ValueCriterionTestFactory.CreateValueCriterion(),
new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
})
});
var lineStyle = new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
};
var mapLineData = new MapLineData("test", lineStyle, theme)
{
Features = new[]
{
CreateMapFeatureWithMetaData(metadataAttribute)
}
};
var mapLineLayer = new MapLineLayer();
var converter = new MapLineDataConverter();
// Call
converter.ConvertLayerProperties(mapLineData, mapLineLayer);
// Assert
ILineSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(lineStyle);
ILineScheme appliedScheme = mapLineLayer.Symbology;
Assert.AreEqual(1, appliedScheme.Categories.Count);
ILineCategory baseCategory = appliedScheme.Categories[0];
AssertAreEqual(expectedSymbolizer, baseCategory.Symbolizer);
Assert.IsNull(baseCategory.FilterExpression);
}
[Test]
public void ConvertLayerProperties_MapLineDataWithThemeAndMetaDataNameInFeatures_ConvertDataToMapLineLayer()
{
// Setup
const string metadataAttribute = "Meta";
var random = new Random(21);
var unequalCriterion = new ValueCriterion(ValueCriterionOperator.UnequalValue,
"unequal value");
var equalCriterion = new ValueCriterion(ValueCriterionOperator.EqualValue,
"equal value");
var theme = new MapTheme(metadataAttribute, new[]
{
new LineCategoryTheme(equalCriterion, new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
}),
new LineCategoryTheme(unequalCriterion, new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
})
});
var lineStyle = new LineStyle
{
Color = Color.FromKnownColor(random.NextEnum()),
Width = random.Next(1, 48),
DashStyle = random.NextEnum()
};
var mapLineData = new MapLineData("test", lineStyle, theme)
{
Features = new[]
{
CreateMapFeatureWithMetaData(metadataAttribute)
}
};
var mapLineLayer = new MapLineLayer();
var converter = new MapLineDataConverter();
// Call
converter.ConvertLayerProperties(mapLineData, mapLineLayer);
// Assert
ILineSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(lineStyle);
ILineScheme appliedScheme = mapLineLayer.Symbology;
Assert.AreEqual(3, appliedScheme.Categories.Count);
ILineCategory baseCategory = appliedScheme.Categories[0];
AssertAreEqual(expectedSymbolizer, baseCategory.Symbolizer);
Assert.IsNull(baseCategory.FilterExpression);
ILineCategory equalSchemeCategory = appliedScheme.Categories[1];
string expectedFilter = $"[1] = '{equalCriterion.Value}'";
Assert.AreEqual(expectedFilter, equalSchemeCategory.FilterExpression);
LineStyle expectedCategoryStyle = theme.CategoryThemes.ElementAt(0).Style;
expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle);
AssertAreEqual(expectedSymbolizer, equalSchemeCategory.Symbolizer);
ILineCategory unEqualSchemeCategory = appliedScheme.Categories[2];
expectedFilter = $"NOT [1] = '{unequalCriterion.Value}'";
Assert.AreEqual(expectedFilter, unEqualSchemeCategory.FilterExpression);
expectedCategoryStyle = theme.CategoryThemes.ElementAt(1).Style;
expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle);
AssertAreEqual(expectedSymbolizer, unEqualSchemeCategory.Symbolizer);
}
private static ILineSymbolizer CreateExpectedSymbolizer(LineStyle expectedLineStyle)
{
DashStyle expectedDashStyle = MapDataHelper.Convert(expectedLineStyle.DashStyle);
Color expectedColor = expectedLineStyle.Color;
return new LineSymbolizer(expectedColor, expectedColor, expectedLineStyle.Width, expectedDashStyle, LineCap.Round);
}
private static MapFeature CreateMapFeatureWithMetaData(string metadataAttributeName)
{
var random = new Random(21);
var mapFeature = new MapFeature(new[]
{
new MapGeometry(new[]
{
new[]
{
new Point2D(random.NextDouble(), random.NextDouble()),
new Point2D(random.NextDouble(), random.NextDouble())
}
})
});
mapFeature.MetaData[metadataAttributeName] = new object();
return mapFeature;
}
private static void AssertAreEqual(ILineSymbolizer firstSymbolizer, ILineSymbolizer secondSymbolizer)
{
IList firstStrokes = firstSymbolizer.Strokes;
IList secondStrokes = secondSymbolizer.Strokes;
Assert.AreEqual(firstStrokes.Count, secondStrokes.Count, "Unequal amount of strokes defined.");
for (var i = 0; i < firstStrokes.Count; i++)
{
var firstStroke = (CartographicStroke) firstStrokes[i];
var secondStroke = (CartographicStroke) secondStrokes[i];
Assert.AreEqual(firstStroke.Color, secondStroke.Color);
Assert.AreEqual(firstStroke.EndCap, secondStroke.EndCap);
Assert.AreEqual(firstStroke.DashStyle, secondStroke.DashStyle);
Assert.AreEqual(firstStroke.Width, secondStroke.Width);
}
}
}
}