Index: Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs =================================================================== diff -u -rcd92c766ed5e85341e84519600878c0f2008fc0e -r4dd90a5aa5bde0397de27124e0979d7a26a5b9b3 --- Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs (.../FeatureBasedMapDataConverter.cs) (revision cd92c766ed5e85341e84519600878c0f2008fc0e) +++ Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs (.../FeatureBasedMapDataConverter.cs) (revision 4dd90a5aa5bde0397de27124e0979d7a26a5b9b3) @@ -134,21 +134,15 @@ /// Creates a new scheme to be applied on the data. /// /// The newly created . - protected virtual IFeatureScheme CreateScheme() - { - return null; - } + protected abstract IFeatureScheme CreateScheme(); /// /// Creates a new based on . /// /// The map data to base the category on. /// The newly created . /// Null should never be returned as this will break DotSpatial. - protected virtual IFeatureCategory CreateDefaultCategory(TFeatureBasedMapData mapData) - { - return null; - } + protected abstract IFeatureCategory CreateDefaultCategory(TFeatureBasedMapData mapData); /// /// Creates a new with a different color than specified in the . @@ -157,10 +151,7 @@ /// The desired color of the category. /// The newly created . /// Null should never be returned as this will break DotSpatial. - protected virtual IFeatureCategory CreateCategory(TFeatureBasedMapData mapData, Color color) - { - return null; - } + protected abstract IFeatureCategory CreateCategory(TFeatureBasedMapData mapData, Color color); /// /// Creates the based on the . Index: Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs =================================================================== diff -u -r876d55bc25a5f8e583bbe02e55e916df8a8e4a20 -r4dd90a5aa5bde0397de27124e0979d7a26a5b9b3 --- Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs (.../MapPolygonDataConverter.cs) (revision 876d55bc25a5f8e583bbe02e55e916df8a8e4a20) +++ Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs (.../MapPolygonDataConverter.cs) (revision 4dd90a5aa5bde0397de27124e0979d7a26a5b9b3) @@ -65,14 +65,35 @@ protected override IFeatureSymbolizer CreateSymbolizer(MapPolygonData mapData) { + return new PolygonSymbolizer(mapData.Style.FillColor, GetStrokeColor(mapData), mapData.Style.StrokeThickness); + } + + private static Color GetStrokeColor(MapPolygonData mapData) + { Color strokeColor = mapData.Style.StrokeColor; if (mapData.Style.StrokeThickness == 0) { strokeColor = Color.Transparent; } - return new PolygonSymbolizer(mapData.Style.FillColor, strokeColor, mapData.Style.StrokeThickness); + + return strokeColor; } + protected override IFeatureScheme CreateScheme() + { + return new PolygonScheme(); + } + + protected override IFeatureCategory CreateDefaultCategory(MapPolygonData mapData) + { + return CreateCategory(mapData, mapData.Style.FillColor); + } + + protected override IFeatureCategory CreateCategory(MapPolygonData mapData, Color color) + { + return new PolygonCategory(color, GetStrokeColor(mapData), mapData.Style.StrokeThickness); + } + private static IBasicGeometry GetGeometry(List geometryList) { IBasicGeometry geometry; Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs =================================================================== diff -u -r2c5e077a0f546af6d6379eb93111fd8366fc2224 -r4dd90a5aa5bde0397de27124e0979d7a26a5b9b3 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs (.../FeatureBasedMapDataConverterTest.cs) (revision 2c5e077a0f546af6d6379eb93111fd8366fc2224) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs (.../FeatureBasedMapDataConverterTest.cs) (revision 4dd90a5aa5bde0397de27124e0979d7a26a5b9b3) @@ -522,6 +522,21 @@ return new PointSymbolizer(); } + protected override IFeatureScheme CreateScheme() + { + throw new NotImplementedException(); + } + + protected override IFeatureCategory CreateDefaultCategory(TestFeatureBasedMapData mapData) + { + throw new NotImplementedException(); + } + + protected override IFeatureCategory CreateCategory(TestFeatureBasedMapData mapData, Color color) + { + throw new NotImplementedException(); + } + protected override IEnumerable CreateFeatures(MapFeature mapFeature) { yield return new Feature(new Point(1.1, 2.2)); Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs =================================================================== diff -u -r66964d0c53eb0d904f7ada3e3bbc1e9604e241e7 -r4dd90a5aa5bde0397de27124e0979d7a26a5b9b3 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs (.../MapPolygonDataConverterTest.cs) (revision 66964d0c53eb0d904f7ada3e3bbc1e9604e241e7) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs (.../MapPolygonDataConverterTest.cs) (revision 4dd90a5aa5bde0397de27124e0979d7a26a5b9b3) @@ -29,6 +29,8 @@ using Core.Components.Gis.Features; using Core.Components.Gis.Geometries; using Core.Components.Gis.Style; +using Core.Components.Gis.Theme; +using Core.Components.Gis.Theme.Criteria; using DotSpatial.Controls; using DotSpatial.Data; using DotSpatial.Symbology; @@ -269,6 +271,189 @@ AssertAreEqual(new PolygonSymbolizer(expectedFillColor, Color.Transparent, 0), mapPolygonLayer.Symbolizer); } + [Test] + public void ConvertLayerProperties_MapPointDataWithStyleAndValueCriteria_ConvertDataToMapPointLayer() + { + // Setup + const string metadataAttribute = "Meta"; + var random = new Random(21); + + var unequalCriteria = new ValueCriteria(ValueCriteriaOperator.UnequalValue, + random.NextDouble()); + var equalCriteria = new ValueCriteria(ValueCriteriaOperator.EqualValue, + random.NextDouble()); + var theme = new MapTheme(metadataAttribute, new[] + { + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + equalCriteria), + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + unequalCriteria) + }); + + var polygonStyle = new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }; + var mapPointData = new MapPolygonData("test", polygonStyle) + { + Features = new[] + { + CreateMapFeatureWithMetaData(metadataAttribute) + }, + MapTheme = theme + }; + + var mapPointLayer = new MapPolygonLayer(); + + var converter = new MapPolygonDataConverter(); + + // Call + converter.ConvertLayerProperties(mapPointData, mapPointLayer); + + // Assert + PolygonSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, polygonStyle.FillColor); + + IPolygonScheme appliedScheme = mapPointLayer.Symbology; + Assert.AreEqual(3, appliedScheme.Categories.Count); + + IPolygonCategory baseCategory = appliedScheme.Categories[0]; + AssertAreEqual(expectedSymbolizer, baseCategory.Symbolizer); + Assert.IsNull(baseCategory.FilterExpression); + + IPolygonCategory equalSchemeCategory = appliedScheme.Categories[1]; + string expectedFilter = $"[1] = {equalCriteria.Value}"; + Assert.AreEqual(expectedFilter, equalSchemeCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(0).Color); + AssertAreEqual(expectedSymbolizer, equalSchemeCategory.Symbolizer); + + IPolygonCategory unEqualSchemeCategory = appliedScheme.Categories[2]; + expectedFilter = $"[1] != {unequalCriteria.Value}"; + Assert.AreEqual(expectedFilter, unEqualSchemeCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(1).Color); + AssertAreEqual(expectedSymbolizer, unEqualSchemeCategory.Symbolizer); + } + + [Test] + public void ConvertLayerProperties_MapPointDataWithStyleAndRangeCriteria_ConvertDataToMapPointLayer() + { + // Setup + const string metadataAttribute = "Meta"; + var random = new Random(21); + + var allBoundsInclusiveCriteria = new RangeCriteria(RangeCriteriaOperator.AllBoundsInclusive, + random.NextDouble(), + 1 + random.NextDouble()); + var lowerBoundInclusiveCriteria = new RangeCriteria(RangeCriteriaOperator.LowerBoundInclusive, + random.NextDouble(), + 1 + random.NextDouble()); + var upperBoundInclusiveCriteria = new RangeCriteria(RangeCriteriaOperator.UpperBoundInclusive, + random.NextDouble(), + 1 + random.NextDouble()); + var allBoundsExclusiveCriteria = new RangeCriteria(RangeCriteriaOperator.AllBoundsExclusive, + random.NextDouble(), + 1 + random.NextDouble()); + var theme = new MapTheme(metadataAttribute, new[] + { + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + allBoundsInclusiveCriteria), + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + lowerBoundInclusiveCriteria), + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + upperBoundInclusiveCriteria), + new CategoryTheme(Color.FromKnownColor(random.NextEnum()), + allBoundsExclusiveCriteria) + }); + + var polygonStyle = new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }; + var mapPointData = new MapPolygonData("test", polygonStyle) + { + Features = new[] + { + CreateMapFeatureWithMetaData(metadataAttribute) + }, + MapTheme = theme + }; + + var mapPointLayer = new MapPolygonLayer(); + + var converter = new MapPolygonDataConverter(); + + // Call + converter.ConvertLayerProperties(mapPointData, mapPointLayer); + + // Assert + PolygonSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, polygonStyle.FillColor); + + IPolygonScheme appliedScheme = mapPointLayer.Symbology; + Assert.AreEqual(5, appliedScheme.Categories.Count); + + IPolygonCategory baseCategory = appliedScheme.Categories[0]; + AssertAreEqual(expectedSymbolizer, baseCategory.Symbolizer); + Assert.IsNull(baseCategory.FilterExpression); + + IPolygonCategory allBoundsInclusiveCategory = appliedScheme.Categories[1]; + string expectedFilter = $"[1] >= {allBoundsInclusiveCriteria.LowerBound} AND [1] <= {allBoundsInclusiveCriteria.UpperBound}"; + Assert.AreEqual(expectedFilter, allBoundsInclusiveCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(0).Color); + AssertAreEqual(expectedSymbolizer, allBoundsInclusiveCategory.Symbolizer); + + IPolygonCategory lowerBoundInclusiveCategory = appliedScheme.Categories[2]; + expectedFilter = $"[1] >= {lowerBoundInclusiveCriteria.LowerBound} AND [1] < {lowerBoundInclusiveCriteria.UpperBound}"; + Assert.AreEqual(expectedFilter, lowerBoundInclusiveCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(1).Color); + AssertAreEqual(expectedSymbolizer, lowerBoundInclusiveCategory.Symbolizer); + + IPolygonCategory upperBoundInclusiveCategory = appliedScheme.Categories[3]; + expectedFilter = $"[1] > {upperBoundInclusiveCriteria.LowerBound} AND [1] <= {upperBoundInclusiveCriteria.UpperBound}"; + Assert.AreEqual(expectedFilter, upperBoundInclusiveCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(2).Color); + AssertAreEqual(expectedSymbolizer, upperBoundInclusiveCategory.Symbolizer); + + IPolygonCategory allBoundsExclusiveCategory = appliedScheme.Categories[4]; + expectedFilter = $"[1] > {allBoundsExclusiveCriteria.LowerBound} AND [1] < {allBoundsExclusiveCriteria.UpperBound}"; + Assert.AreEqual(expectedFilter, allBoundsExclusiveCategory.FilterExpression); + expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, + theme.CategoryThemes.ElementAt(3).Color); + AssertAreEqual(expectedSymbolizer, allBoundsExclusiveCategory.Symbolizer); + } + + 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()) + } + }) + }); + mapFeature.MetaData[metadataAttributeName] = new object(); + + return mapFeature; + } + + private static PolygonSymbolizer CreateExpectedSymbolizer(PolygonStyle expectedPolygonStyle, + Color expectedFillColor) + { + var expectedSymbolizer = new PolygonSymbolizer(expectedFillColor, expectedPolygonStyle.StrokeColor, expectedPolygonStyle.StrokeThickness); + return expectedSymbolizer; + } + private static Point2D[] CreateRectangularRing(double xy1, double xy2) { return new[]