Index: Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs =================================================================== diff -u -r3f64435bdc16678eb063fd02f1dd1cb2e0f9e535 -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs (.../FeatureBasedMapDataConverter.cs) (revision 3f64435bdc16678eb063fd02f1dd1cb2e0f9e535) +++ Core/Components/src/Core.Components.DotSpatial/Converter/FeatureBasedMapDataConverter.cs (.../FeatureBasedMapDataConverter.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -220,11 +220,16 @@ } } + /// + /// Gets the mapping between map data attribute names and DotSpatial attribute names. + /// + /// The map data to get the mappings from. + /// The mapping between map data attribute names and DotSpatial attribute names. /// /// This method is used for obtaining a mapping between map data attribute names and DotSpatial /// attribute names. This mapping is needed because DotSpatial can't handle special characters. /// - private static Dictionary GetAttributeMapping(TFeatureBasedMapData data) + protected static Dictionary GetAttributeMapping(TFeatureBasedMapData data) { return Enumerable.Range(0, data.MetaData.Count()) .ToDictionary(md => data.MetaData.ElementAt(md), mdi => mdi + 1); @@ -258,7 +263,7 @@ /// and . /// Thrown when the /// cannot be used to create a filter expression. - private static string CreateFilterExpression(int attributeIndex, ValueCriterion criterion) + protected static string CreateFilterExpression(int attributeIndex, ValueCriterion criterion) { ValueCriterionOperator valueOperator = criterion.ValueOperator; switch (valueOperator) Index: Core/Components/src/Core.Components.DotSpatial/Converter/MapLineDataConverter.cs =================================================================== diff -u -r2a81f01756e227d5ce93717b21b87e8a5cd5fcbb -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/src/Core.Components.DotSpatial/Converter/MapLineDataConverter.cs (.../MapLineDataConverter.cs) (revision 2a81f01756e227d5ce93717b21b87e8a5cd5fcbb) +++ Core/Components/src/Core.Components.DotSpatial/Converter/MapLineDataConverter.cs (.../MapLineDataConverter.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -20,16 +20,17 @@ // All rights reserved. using System.Collections.Generic; -using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using Core.Common.Base.Geometry; using Core.Components.Gis.Data; using Core.Components.Gis.Features; +using Core.Components.Gis.Theme; using DotSpatial.Controls; using DotSpatial.Data; using DotSpatial.Symbology; using DotSpatial.Topology; +using LineStyle = Core.Components.Gis.Style.LineStyle; namespace Core.Components.DotSpatial.Converter { @@ -52,22 +53,46 @@ LineCap.Round); } - protected override IFeatureScheme CreateScheme() + protected override IFeatureCategory CreateDefaultCategory(MapLineData mapData) { - return new LineScheme(); + return CreateCategory(mapData.Style); } - protected override IFeatureCategory CreateDefaultCategory(MapLineData mapData) + protected override bool HasMapTheme(MapLineData mapData) { - return CreateCategory(mapData, mapData.Style.Color); + return mapData.Theme != null; } - protected override IFeatureCategory CreateCategory(MapLineData mapData, Color color) + protected override IFeatureScheme CreateCategoryScheme(MapLineData mapData) { - return new LineCategory(color, - color, - mapData.Style.Width, - MapDataHelper.Convert(mapData.Style.DashStyle), + var scheme = new LineScheme(); + scheme.ClearCategories(); + scheme.AddCategory(CreateCategory(mapData.Style)); + + MapTheme mapTheme = mapData.Theme; + Dictionary attributeMapping = GetAttributeMapping(mapData); + + if (attributeMapping.ContainsKey(mapTheme.AttributeName)) + { + int attributeIndex = attributeMapping[mapTheme.AttributeName]; + + foreach (LineCategoryTheme categoryTheme in mapTheme.CategoryThemes) + { + IFeatureCategory category = CreateCategory(categoryTheme.Style); + category.FilterExpression = CreateFilterExpression(attributeIndex, categoryTheme.Criterion); + scheme.AddCategory(category); + } + } + + return scheme; + } + + private static IFeatureCategory CreateCategory(LineStyle style) + { + return new LineCategory(style.Color, + style.Color, + style.Width, + MapDataHelper.Convert(style.DashStyle), LineCap.Round); } Index: Core/Components/src/Core.Components.DotSpatial/Converter/MapPointDataConverter.cs =================================================================== diff -u -r2a81f01756e227d5ce93717b21b87e8a5cd5fcbb -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/src/Core.Components.DotSpatial/Converter/MapPointDataConverter.cs (.../MapPointDataConverter.cs) (revision 2a81f01756e227d5ce93717b21b87e8a5cd5fcbb) +++ Core/Components/src/Core.Components.DotSpatial/Converter/MapPointDataConverter.cs (.../MapPointDataConverter.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -20,15 +20,15 @@ // All rights reserved. using System.Collections.Generic; -using System.Drawing; using System.Linq; using Core.Components.Gis.Data; using Core.Components.Gis.Features; +using Core.Components.Gis.Style; +using Core.Components.Gis.Theme; using DotSpatial.Controls; using DotSpatial.Data; using DotSpatial.Symbology; using DotSpatial.Topology; -using Point = DotSpatial.Topology.Point; namespace Core.Components.DotSpatial.Converter { @@ -44,33 +44,52 @@ protected override IFeatureSymbolizer CreateSymbolizer(MapPointData mapData) { - return CreatePointSymbolizer(mapData); + return CreatePointSymbolizer(mapData.Style); } - protected override IFeatureScheme CreateScheme() + protected override IFeatureCategory CreateDefaultCategory(MapPointData mapData) { - return new PointScheme(); + return CreateCategory(mapData.Style); } - protected override IFeatureCategory CreateDefaultCategory(MapPointData mapData) + protected override bool HasMapTheme(MapPointData mapData) { - return CreateCategory(mapData, mapData.Style.Color); + return mapData.Theme != null; } - protected override IFeatureCategory CreateCategory(MapPointData mapData, Color color) + protected override IFeatureScheme CreateCategoryScheme(MapPointData mapData) { - PointSymbolizer symbolizer = CreatePointSymbolizer(mapData); + var scheme = new PointScheme(); + scheme.ClearCategories(); + scheme.AddCategory(CreateCategory(mapData.Style)); - var category = new PointCategory(symbolizer); - category.SetColor(color); + MapTheme mapTheme = mapData.Theme; + Dictionary attributeMapping = GetAttributeMapping(mapData); - return category; + if (attributeMapping.ContainsKey(mapTheme.AttributeName)) + { + int attributeIndex = attributeMapping[mapTheme.AttributeName]; + + foreach (PointCategoryTheme categoryTheme in mapTheme.CategoryThemes) + { + IFeatureCategory category = CreateCategory(categoryTheme.Style); + category.FilterExpression = CreateFilterExpression(attributeIndex, categoryTheme.Criterion); + scheme.AddCategory(category); + } + } + + return scheme; } - private static PointSymbolizer CreatePointSymbolizer(MapPointData mapData) + private static IFeatureCategory CreateCategory(PointStyle pointStyle) { - var symbolizer = new PointSymbolizer(mapData.Style.Color, MapDataHelper.Convert(mapData.Style.Symbol), mapData.Style.Size); - symbolizer.SetOutline(mapData.Style.StrokeColor, mapData.Style.StrokeThickness); + return new PointCategory(CreatePointSymbolizer(pointStyle)); + } + + private static PointSymbolizer CreatePointSymbolizer(PointStyle style) + { + var symbolizer = new PointSymbolizer(style.Color, MapDataHelper.Convert(style.Symbol), style.Size); + symbolizer.SetOutline(style.StrokeColor, style.StrokeThickness); return symbolizer; } Index: Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs =================================================================== diff -u -r2a81f01756e227d5ce93717b21b87e8a5cd5fcbb -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs (.../MapPolygonDataConverter.cs) (revision 2a81f01756e227d5ce93717b21b87e8a5cd5fcbb) +++ Core/Components/src/Core.Components.DotSpatial/Converter/MapPolygonDataConverter.cs (.../MapPolygonDataConverter.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -26,6 +26,8 @@ using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.Geometries; +using Core.Components.Gis.Style; +using Core.Components.Gis.Theme; using DotSpatial.Controls; using DotSpatial.Data; using DotSpatial.Symbology; @@ -65,28 +67,52 @@ protected override IFeatureSymbolizer CreateSymbolizer(MapPolygonData mapData) { - return new PolygonSymbolizer(mapData.Style.FillColor, GetStrokeColor(mapData), mapData.Style.StrokeThickness); + return new PolygonSymbolizer(mapData.Style.FillColor, GetStrokeColor(mapData.Style), mapData.Style.StrokeThickness); } - protected override IFeatureScheme CreateScheme() + protected override IFeatureCategory CreateDefaultCategory(MapPolygonData mapData) { - return new PolygonScheme(); + return CreateCategory(mapData.Style); } - protected override IFeatureCategory CreateDefaultCategory(MapPolygonData mapData) + protected override bool HasMapTheme(MapPolygonData mapData) { - return CreateCategory(mapData, mapData.Style.FillColor); + return mapData.Theme != null; } - protected override IFeatureCategory CreateCategory(MapPolygonData mapData, Color color) + protected override IFeatureScheme CreateCategoryScheme(MapPolygonData mapData) { - return new PolygonCategory(color, GetStrokeColor(mapData), mapData.Style.StrokeThickness); + var scheme = new PolygonScheme(); + scheme.ClearCategories(); + scheme.AddCategory(CreateCategory(mapData.Style)); + + MapTheme mapTheme = mapData.Theme; + Dictionary attributeMapping = GetAttributeMapping(mapData); + + if (attributeMapping.ContainsKey(mapTheme.AttributeName)) + { + int attributeIndex = attributeMapping[mapTheme.AttributeName]; + + foreach (PolygonCategoryTheme categoryTheme in mapTheme.CategoryThemes) + { + IFeatureCategory category = CreateCategory(categoryTheme.Style); + category.FilterExpression = CreateFilterExpression(attributeIndex, categoryTheme.Criterion); + scheme.AddCategory(category); + } + } + + return scheme; } - private static Color GetStrokeColor(MapPolygonData mapData) + private static IFeatureCategory CreateCategory(PolygonStyle style) { - Color strokeColor = mapData.Style.StrokeColor; - if (mapData.Style.StrokeThickness == 0) + return new PolygonCategory(style.FillColor, GetStrokeColor(style), style.StrokeThickness); + } + + private static Color GetStrokeColor(PolygonStyle style) + { + Color strokeColor = style.StrokeColor; + if (style.StrokeThickness == 0) { strokeColor = Color.Transparent; } Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs =================================================================== diff -u -r3f64435bdc16678eb063fd02f1dd1cb2e0f9e535 -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs (.../FeatureBasedMapDataConverterTest.cs) (revision 3f64435bdc16678eb063fd02f1dd1cb2e0f9e535) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/FeatureBasedMapDataConverterTest.cs (.../FeatureBasedMapDataConverterTest.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -538,10 +538,6 @@ public void ConvertLayerProperties_MapDataHasMapTheme_SetsSymbology() { // Setup - var mocks = new MockRepository(); - var scheme = mocks.Stub(); - mocks.ReplayAll(); - var mapLayer = new TestFeatureLayer(); var mapData = new TestFeatureBasedMapData("test data") { @@ -551,6 +547,7 @@ } }; + var scheme = new PointScheme(); var testConverter = new TestFeatureBasedMapDataConverter { CreatedFeatureScheme = scheme, @@ -562,17 +559,12 @@ // Assert Assert.AreSame(scheme, mapLayer.Symbology); - mocks.VerifyAll(); } [Test] public void ConvertLayerProperties_MapDataHasMapTheme_CallsCreateCategorySchemeWithCorrectInput() { // Setup - var mocks = new MockRepository(); - var scheme = mocks.Stub(); - mocks.ReplayAll(); - var mapData = new TestFeatureBasedMapData("test data") { Features = new[] @@ -581,6 +573,7 @@ } }; + var scheme = new PointScheme(); var testConverter = new TestFeatureBasedMapDataConverter { CreatedFeatureScheme = scheme, @@ -594,7 +587,6 @@ // Assert Assert.AreSame(mapData, testConverter.MapDataInput); - mocks.VerifyAll(); } [Test] @@ -626,6 +618,7 @@ mocks.ReplayAll(); var scheme = new PointScheme(); + scheme.Categories.Clear(); scheme.Categories.Add(categoryOne); scheme.Categories.Add(categoryTwo); @@ -637,7 +630,7 @@ var testConverter = new TestFeatureBasedMapDataConverter { CreatedDefaultCategory = defaultCategory, - MapDataHasTheme = true + MapDataHasTheme = true }; // Precondition @@ -681,6 +674,7 @@ protected override bool HasMapTheme(TestFeatureBasedMapData mapData) { + MapDataInput = mapData; return MapDataHasTheme; } Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapLineDataConverterTest.cs =================================================================== diff -u -r4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4 -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapLineDataConverterTest.cs (.../MapLineDataConverterTest.cs) (revision 4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapLineDataConverterTest.cs (.../MapLineDataConverterTest.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -30,12 +30,14 @@ 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 DotSpatial.Topology; using NUnit.Framework; +using Rhino.Mocks; using LineStyle = Core.Components.Gis.Style.LineStyle; namespace Core.Components.DotSpatial.Test.Converter @@ -167,6 +169,69 @@ } [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) + { + Features = new[] + { + CreateMapFeatureWithMetaData("Meta") + }, + Theme = theme + }; + + // 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)] @@ -204,27 +269,35 @@ "unequal value"); var equalCriterion = new ValueCriterion(ValueCriterionOperator.EqualValue, "equal value"); - var theme = new MapTheme(metadataAttribute, new[] + var theme = new MapTheme(metadataAttribute, new[] { - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - equalCriterion), - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - unequalCriterion) + 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 = LineDashStyle.DashDotDot + DashStyle = random.NextEnum() }; var mapLineData = new MapLineData("test", lineStyle) { Features = new[] { CreateMapFeatureWithMetaData(metadataAttribute) }, - MapTheme = theme + Theme = theme }; var mapLineLayer = new MapLineLayer(); @@ -235,10 +308,7 @@ converter.ConvertLayerProperties(mapLineData, mapLineLayer); // Assert - const DashStyle expectedDashStyle = DashStyle.DashDotDot; - ILineSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(lineStyle, - expectedDashStyle, - lineStyle.Color); + ILineSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(lineStyle); ILineScheme appliedScheme = mapLineLayer.Symbology; Assert.AreEqual(3, appliedScheme.Categories.Count); @@ -250,24 +320,22 @@ ILineCategory equalSchemeCategory = appliedScheme.Categories[1]; string expectedFilter = $"[1] = '{equalCriterion.Value}'"; Assert.AreEqual(expectedFilter, equalSchemeCategory.FilterExpression); - expectedSymbolizer = CreateExpectedSymbolizer(lineStyle, - expectedDashStyle, - theme.CategoryThemes.ElementAt(0).Color); + 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); - expectedSymbolizer = CreateExpectedSymbolizer(lineStyle, - expectedDashStyle, - theme.CategoryThemes.ElementAt(1).Color); + expectedCategoryStyle = theme.CategoryThemes.ElementAt(1).Style; + expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle); AssertAreEqual(expectedSymbolizer, unEqualSchemeCategory.Symbolizer); } - private static ILineSymbolizer CreateExpectedSymbolizer(LineStyle expectedLineStyle, - DashStyle expectedDashStyle, - Color expectedColor) + 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); } @@ -280,6 +348,7 @@ { new[] { + new Point2D(random.NextDouble(), random.NextDouble()), new Point2D(random.NextDouble(), random.NextDouble()) } }) Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPointDataConverterTest.cs =================================================================== diff -u -r4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4 -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPointDataConverterTest.cs (.../MapPointDataConverterTest.cs) (revision 4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPointDataConverterTest.cs (.../MapPointDataConverterTest.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -29,12 +29,14 @@ 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 DotSpatial.Topology; using NUnit.Framework; +using Rhino.Mocks; using Point = DotSpatial.Topology.Point; using PointShape = DotSpatial.Symbology.PointShape; @@ -150,6 +152,74 @@ } [Test] + public void GivenMapLayerWithScheme_WhenConvertingLayerFeatures_ThenClearsAppliedSchemeAndAppliesDefaultCategory() + { + // Given + const string metadataAttribute = "Meta"; + + var mocks = new MockRepository(); + var categoryOne = mocks.Stub(); + var categoryTwo = mocks.Stub(); + mocks.ReplayAll(); + + var mapLineLayer = new MapPointLayer + { + Symbology = new PointScheme + { + Categories = + { + categoryOne, + categoryTwo + } + } + }; + + var converter = new MapPointDataConverter(); + + var random = new Random(21); + var pointStyle = new PointStyle + { + Color = Color.FromKnownColor(random.NextEnum()), + Size = random.Next(1, 48), + Symbol = random.NextEnum(), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }; + var theme = new MapTheme(metadataAttribute, new[] + { + new PointCategoryTheme(ValueCriterionTestFactory.CreateValueCriterion(), + new PointStyle + { + Color = Color.FromKnownColor(random.NextEnum()), + Size = random.Next(1, 48), + Symbol = random.NextEnum(), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }) + }); + var mapPointData = new MapPointData("test", pointStyle) + { + Features = new[] + { + CreateMapFeatureWithMetaData(metadataAttribute) + }, + Theme = theme + }; + + // When + converter.ConvertLayerFeatures(mapPointData, mapLineLayer); + + // Then + PointCategoryCollection categoryCollection = mapLineLayer.Symbology.Categories; + Assert.AreEqual(1, categoryCollection.Count); + + IPointSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(pointStyle); + AssertAreEqual(expectedSymbolizer, categoryCollection.Single().Symbolizer); + + mocks.VerifyAll(); + } + + [Test] [Combinatorial] public void ConvertLayerProperties_MapPointDataWithStyle_ConvertsStyleToMapPointLayer( [Values(KnownColor.AliceBlue, KnownColor.Azure)] @@ -196,19 +266,31 @@ "unequal value"); var equalCriterion = new ValueCriterion(ValueCriterionOperator.EqualValue, "equal value"); - var theme = new MapTheme(metadataAttribute, new[] + var theme = new MapTheme(metadataAttribute, new[] { - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - equalCriterion), - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - unequalCriterion) + new PointCategoryTheme(equalCriterion, new PointStyle + { + Color = Color.FromKnownColor(random.NextEnum()), + Size = random.Next(1, 48), + Symbol = random.NextEnum(), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }), + new PointCategoryTheme(unequalCriterion, new PointStyle + { + Color = Color.FromKnownColor(random.NextEnum()), + Size = random.Next(1, 48), + Symbol = random.NextEnum(), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }) }); var pointStyle = new PointStyle { Color = Color.FromKnownColor(random.NextEnum()), Size = random.Next(1, 48), - Symbol = PointSymbol.Circle, + Symbol = random.NextEnum(), StrokeColor = Color.FromKnownColor(random.NextEnum()), StrokeThickness = random.Next(1, 48) }; @@ -218,7 +300,7 @@ { CreateMapFeatureWithMetaData(metadataAttribute) }, - MapTheme = theme + Theme = theme }; var mapPointLayer = new MapPointLayer(); @@ -229,10 +311,7 @@ converter.ConvertLayerProperties(mapPointData, mapPointLayer); // Assert - const PointShape expectedPointShape = PointShape.Ellipse; - PointSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(pointStyle, - expectedPointShape, - pointStyle.Color); + PointSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(pointStyle); IPointScheme appliedScheme = mapPointLayer.Symbology; Assert.AreEqual(3, appliedScheme.Categories.Count); @@ -244,25 +323,23 @@ IPointCategory equalSchemeCategory = appliedScheme.Categories[1]; string expectedFilter = $"[1] = '{equalCriterion.Value}'"; Assert.AreEqual(expectedFilter, equalSchemeCategory.FilterExpression); - expectedSymbolizer = CreateExpectedSymbolizer(pointStyle, - expectedPointShape, - theme.CategoryThemes.ElementAt(0).Color); + PointStyle expectedCategoryStyle = theme.CategoryThemes.ElementAt(0).Style; + expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle); AssertAreEqual(expectedSymbolizer, equalSchemeCategory.Symbolizer); IPointCategory unEqualSchemeCategory = appliedScheme.Categories[2]; expectedFilter = $"NOT [1] = '{unequalCriterion.Value}'"; Assert.AreEqual(expectedFilter, unEqualSchemeCategory.FilterExpression); - expectedSymbolizer = CreateExpectedSymbolizer(pointStyle, - expectedPointShape, - theme.CategoryThemes.ElementAt(1).Color); + expectedCategoryStyle = theme.CategoryThemes.ElementAt(1).Style; + expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle); AssertAreEqual(expectedSymbolizer, unEqualSchemeCategory.Symbolizer); } - private static PointSymbolizer CreateExpectedSymbolizer(PointStyle expectedPointStyle, - PointShape expectedPointShape, - Color expectedColor) + private static PointSymbolizer CreateExpectedSymbolizer(PointStyle expectedPointStyle) { - var expectedSymbolizer = new PointSymbolizer(expectedColor, expectedPointShape, expectedPointStyle.Size); + PointShape expectedPointShape = MapDataHelper.Convert(expectedPointStyle.Symbol); + + var expectedSymbolizer = new PointSymbolizer(expectedPointStyle.Color, expectedPointShape, expectedPointStyle.Size); expectedSymbolizer.SetOutline(expectedPointStyle.StrokeColor, expectedPointStyle.StrokeThickness); return expectedSymbolizer; Index: Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs =================================================================== diff -u -r4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4 -r35f8077602c4054df008af5ae79d7b2d33d32011 --- Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs (.../MapPolygonDataConverterTest.cs) (revision 4c7e3ff3bf5c0a50fd9d208b71400e5dfb6cebd4) +++ Core/Components/test/Core.Components.DotSpatial.Test/Converter/MapPolygonDataConverterTest.cs (.../MapPolygonDataConverterTest.cs) (revision 35f8077602c4054df008af5ae79d7b2d33d32011) @@ -29,12 +29,14 @@ 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 DotSpatial.Topology; using NUnit.Framework; +using Rhino.Mocks; namespace Core.Components.DotSpatial.Test.Converter { @@ -223,6 +225,70 @@ } [Test] + public void GivenMapLayerWithScheme_WhenConvertingLayerFeatures_ThenClearsAppliedSchemeAndAppliesDefaultCategory() + { + // Given + const string metadataAttribute = "Meta"; + + var mocks = new MockRepository(); + var categoryOne = mocks.Stub(); + var categoryTwo = mocks.Stub(); + mocks.ReplayAll(); + + var mapLineLayer = new MapPolygonLayer + { + Symbology = new PolygonScheme + { + Categories = + { + categoryOne, + categoryTwo + } + } + }; + + var converter = new MapPolygonDataConverter(); + + var random = new Random(21); + var polygonStyle = new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }; + var theme = new MapTheme(metadataAttribute, new[] + { + new PolygonCategoryTheme(ValueCriterionTestFactory.CreateValueCriterion(), + new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }) + }); + var mapPolygonData = new MapPolygonData("test", polygonStyle) + { + Features = new[] + { + CreateMapFeatureWithMetaData(metadataAttribute) + }, + Theme = theme + }; + + // When + converter.ConvertLayerFeatures(mapPolygonData, mapLineLayer); + + // Then + PolygonCategoryCollection categoryCollection = mapLineLayer.Symbology.Categories; + Assert.AreEqual(1, categoryCollection.Count); + + PolygonSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle); + AssertAreEqual(expectedSymbolizer, categoryCollection.Single().Symbolizer); + + mocks.VerifyAll(); + } + + [Test] [Combinatorial] public void ConvertLayerProperties_MapPolygonDataWithStyle_ConvertsStyleToMapPolygonLayer( [Values(KnownColor.AliceBlue, KnownColor.Azure)] @@ -283,12 +349,20 @@ "unequal value"); var equalCriterion = new ValueCriterion(ValueCriterionOperator.EqualValue, "equal value"); - var theme = new MapTheme(metadataAttribute, new[] + var theme = new MapTheme(metadataAttribute, new[] { - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - equalCriterion), - new CategoryTheme(Color.FromKnownColor(random.NextEnum()), - unequalCriterion) + new PolygonCategoryTheme(equalCriterion, new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }), + new PolygonCategoryTheme(unequalCriterion, new PolygonStyle + { + FillColor = Color.FromKnownColor(random.NextEnum()), + StrokeColor = Color.FromKnownColor(random.NextEnum()), + StrokeThickness = random.Next(1, 48) + }) }); var polygonStyle = new PolygonStyle @@ -303,7 +377,7 @@ { CreateMapFeatureWithMetaData(metadataAttribute) }, - MapTheme = theme + Theme = theme }; var mapPointLayer = new MapPolygonLayer(); @@ -314,7 +388,7 @@ converter.ConvertLayerProperties(mapPointData, mapPointLayer); // Assert - PolygonSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, polygonStyle.FillColor); + PolygonSymbolizer expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle); IPolygonScheme appliedScheme = mapPointLayer.Symbology; Assert.AreEqual(3, appliedScheme.Categories.Count); @@ -326,15 +400,15 @@ IPolygonCategory equalSchemeCategory = appliedScheme.Categories[1]; string expectedFilter = $"[1] = '{equalCriterion.Value}'"; Assert.AreEqual(expectedFilter, equalSchemeCategory.FilterExpression); - expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, - theme.CategoryThemes.ElementAt(0).Color); + PolygonStyle expectedCategoryStyle = theme.CategoryThemes.ElementAt(0).Style; + expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle); AssertAreEqual(expectedSymbolizer, equalSchemeCategory.Symbolizer); IPolygonCategory unEqualSchemeCategory = appliedScheme.Categories[2]; expectedFilter = $"NOT [1] = '{unequalCriterion.Value}'"; Assert.AreEqual(expectedFilter, unEqualSchemeCategory.FilterExpression); - expectedSymbolizer = CreateExpectedSymbolizer(polygonStyle, - theme.CategoryThemes.ElementAt(1).Color); + expectedCategoryStyle = theme.CategoryThemes.ElementAt(1).Style; + expectedSymbolizer = CreateExpectedSymbolizer(expectedCategoryStyle); AssertAreEqual(expectedSymbolizer, unEqualSchemeCategory.Symbolizer); } @@ -347,6 +421,7 @@ { new[] { + new Point2D(random.NextDouble(), random.NextDouble()), new Point2D(random.NextDouble(), random.NextDouble()) } }) @@ -356,11 +431,9 @@ return mapFeature; } - private static PolygonSymbolizer CreateExpectedSymbolizer(PolygonStyle expectedPolygonStyle, - Color expectedFillColor) + private static PolygonSymbolizer CreateExpectedSymbolizer(PolygonStyle expectedPolygonStyle) { - var expectedSymbolizer = new PolygonSymbolizer(expectedFillColor, expectedPolygonStyle.StrokeColor, expectedPolygonStyle.StrokeThickness); - return expectedSymbolizer; + return new PolygonSymbolizer(expectedPolygonStyle.FillColor, expectedPolygonStyle.StrokeColor, expectedPolygonStyle.StrokeThickness); } private static Point2D[] CreateRectangularRing(double xy1, double xy2)