[mapguide-commits] r8267 - in sandbox/jng/convenience_apis: Common/MapGuideCommon/MapLayer Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Jun 27 02:35:56 PDT 2014


Author: jng
Date: 2014-06-27 02:35:56 -0700 (Fri, 27 Jun 2014)
New Revision: 8267

Modified:
   sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp
   sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h
   sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp
   sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h
Log:
For layers with multiple composite styles, the current set of APIs won't cut it, as theme category for composite styles needs to be offset by the number of rules in other styles before it in order for the right icon to be rendered.

This submission adds a GetCompositeThemeCategoryCount method to support this scenario. Also included is unit tests for exercising this particular case, and demonstrating how composite theme icons would be generated.

Modified: sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp
===================================================================
--- sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp	2014-06-26 15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp	2014-06-27 09:35:56 UTC (rev 8267)
@@ -628,8 +628,7 @@
                             }
                             else if (cts != NULL)
                             {
-                                if (ret->IndexOf(4) < 0)
-                                    ret->Add(4);
+                                ret->Add(4);
                             }
                         }
                     }
@@ -700,6 +699,51 @@
     return ret;
 }
 
+INT32 MgLayer::GetCompositeThemeCategoryCount(INT32 compositeOffset)
+{
+    return GetCompositeThemeCategoryCount(GetMap()->GetViewScale(), compositeOffset);
+}
+
+INT32 MgLayer::GetCompositeThemeCategoryCount(double scale, INT32 compositeOffset)
+{
+    INT32 ret = -1;
+
+    Ptr<MgResourceService> resSvc = dynamic_cast<MgResourceService*>(GetMap()->GetService(MgServiceType::ResourceService));
+    std::auto_ptr<MdfModel::LayerDefinition> ldf(MgLayerBase::GetLayerDefinition(resSvc, m_definition));
+    if (ldf.get() != NULL)
+    {
+        MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(ldf.get());
+        if(vl != NULL)
+        {
+            MdfModel::VectorScaleRangeCollection* scaleRanges = vl->GetScaleRanges();
+            if (scaleRanges != NULL)
+            {
+                for (INT32 i = 0; i < scaleRanges->GetCount(); i++)
+                {
+                    MdfModel::VectorScaleRange* vsr = scaleRanges->GetAt(i);
+                    if (scale >= vsr->GetMinScale() && scale < vsr->GetMaxScale())
+                    {
+                        MdfModel::FeatureTypeStyleCollection* ftsc = vsr->GetFeatureTypeStyles();
+                        //NOTE: If a Layer Definition has basic and composite types, then this offset will probably be wrong
+                        //but such layers are technically illegal and we shouldn't try to be catering to such layers
+                        if (compositeOffset < ftsc->GetCount())
+                        {
+                            MdfModel::CompositeTypeStyle* cts = dynamic_cast<MdfModel::CompositeTypeStyle*>(ftsc->GetAt(compositeOffset));
+                            if (cts != NULL)
+                            {
+                                ret = cts->GetRules()->GetCount();
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    return ret;
+}
+
 MgByteReader* MgLayer::GenerateLegendImage(double scale, INT32 width, INT32 height, CREFSTRING format, INT32 geomType, INT32 themeCategory)
 {
     Ptr<MgByteReader> ret;

Modified: sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h
===================================================================
--- sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h	2014-06-26 15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h	2014-06-27 09:35:56 UTC (rev 8267)
@@ -377,7 +377,8 @@
     /// \htmlinclude SyntaxBottom.html
     ///
     /// \remarks
-    /// The map's current scale is used to determine what scale range in the layer definition to search for
+    /// The map's current scale is used to determine what scale range in the layer definition to search for.
+    /// For a scale range with multiple composite styles, multiple instances of (4 = composite) will be in the resulting collection
     ///
     /// \return
     /// The list of geometry type styles for this layer at the map's current scale. Returns NULL if there are no applicable geometry types
@@ -404,7 +405,9 @@
     /// The geometry type
     ///
     /// \remarks
-    /// The map's current scale is used to determine what scale range in the layer definition to search for
+    /// The map's current scale is used to determine what scale range in the layer definition to search for.
+    /// When geomType = 4, it will only count the number of the theme categories for the first composite style it finds. For a scale range
+    /// with multiple composite type styles, you should use GetCompositeThemeCategoryCount() instead
     ///
     /// \return
     /// The number of theme categories for this layer at the map's current scale for the given geometry type style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
@@ -412,6 +415,30 @@
     /// \since 3.0
     INT32 GetThemeCategoryCount(INT32 geomType);
 
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the number of composite theme categories for this layer at the map's current scale for the given composite style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
+    ///
+    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \param compositeOffset (int)
+    /// The zero-based index denoting the particular composite style to count from. 0 = 1st composite style, 1 = 2nd composite style
+    ///
+    /// \return
+    /// The number of theme categories for this layer at the map's current scale for the given composite style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
+    ///
+    /// \since 3.0
+    INT32 GetCompositeThemeCategoryCount(INT32 compositeOffset);
+
     ////////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the legend image for the specified geometry type and theme category
@@ -486,6 +513,9 @@
     /// \param scale (double)
     /// The scale at which to retrive the list of applicable geometry types
     ///
+    /// \remarks
+    /// For a scale range with multiple composite styles, multiple instances of (4 = composite) will be in the resulting collection
+    ///
     /// \return
     /// The list of geometry type styles for this layer at the map's current scale. Returns NULL if there are no applicable geometry types
     ///
@@ -512,12 +542,42 @@
     /// \param geomType (int)
     /// The geometry type
     ///
+    /// \remarks
+    /// When geomType = 4, it will only count the number of the theme categories for the first composite style it finds. For a scale range
+    /// with multiple composite type styles, you should use GetCompositeThemeCategoryCount() instead
+    ///
     /// \return
     /// The number of theme categories for this layer at the map's current scale for the given geometry type style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
     ///
     /// \since 3.0
     INT32 GetThemeCategoryCount(double scale, INT32 geomType);
 
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the number of composite theme categories for this layer at the map's current scale for the given composite style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
+    ///
+    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \param scale (double)
+    /// The scale at which to count the number of applicable theme categories
+    /// \param compositeOffset (int)
+    /// The zero-based index denoting the particular composite style to count from. 0 = 1st composite style, 1 = 2nd composite style
+    ///
+    /// \return
+    /// The number of theme categories for this layer at the map's current scale for the given composite style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
+    ///
+    /// \since 3.0
+    INT32 GetCompositeThemeCategoryCount(double scale, INT32 compositeOffset);
+
     ////////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the legend image for the specified geometry type and theme category

Modified: sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp
===================================================================
--- sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp	2014-06-26 15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp	2014-06-27 09:35:56 UTC (rev 8267)
@@ -128,6 +128,16 @@
         Ptr<MgByteReader> ldfrdr4 = ldfsrc4->GetReader();
         m_svcResource->SetResource(ldfres4, ldfrdr4, NULL);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc5 = new MgByteSource(L"../UnitTestFiles/UT_MultiCTS.ldf", false);
+        Ptr<MgByteReader> ldfrdr5 = ldfsrc5->GetReader();
+        m_svcResource->SetResource(ldfres5, ldfrdr5, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc6 = new MgByteSource(L"../UnitTestFiles/UT_MultiCTSWithTheme.ldf", false);
+        Ptr<MgByteReader> ldfrdr6 = ldfsrc6->GetReader();
+        m_svcResource->SetResource(ldfres6, ldfrdr6, NULL);
+
         //publish the feature sources
         Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
         Ptr<MgByteSource> fssrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.fs", false);
@@ -216,6 +226,12 @@
         Ptr<MgResourceIdentifier> ldfres4 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RotatedPointStyles.LayerDefinition");
         m_svcResource->DeleteResource(ldfres4);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres5);
+
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres6);
+
         //delete the feature sources
         Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
         m_svcResource->DeleteResource(fsres1);
@@ -1082,6 +1098,181 @@
     }
 }
 
+void TestMappingService::TestCase_GetLegendImageCompositeConvenience()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map = new MgMap(m_siteConnection);
+        map->Create(mapres, L"TestCase_GetLegendImageCompositeConvenience");
+
+        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition");
+        Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource);
+        layer->SetName(L"TestCase_GetLegendImageCompositeConvenience");
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+
+        Ptr<MgIntCollection> types = layer->GetGeometryTypeStyles(10000.0);
+        CPPUNIT_ASSERT(3 == types->GetCount());
+        CPPUNIT_ASSERT(types->IndexOf(1) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(2) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(3) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(4) >= 0);
+        for (INT32 i = 0; i < types->GetCount(); i++)
+        {
+            CPPUNIT_ASSERT(4 == types->GetItem(i));
+        }
+
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 3));
+        CPPUNIT_ASSERT(1 == layer->GetThemeCategoryCount(10000.0, 4));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 0));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetCompositeThemeCategoryCount(10000.0, 3));
+
+        INT32 rulesProcessed = 0;
+        for (INT32 ctype = 0; ctype < 3; ctype++)
+        {
+            INT32 rules = layer->GetCompositeThemeCategoryCount(10000.0, ctype);
+            for (INT32 offset = rulesProcessed; offset < (rulesProcessed + rules); offset++)
+            {
+                STRING prefix = L"../UnitTestFiles/GenerateLegendImageConvenience_MultiCTS_type";
+                STRING sNum;
+                MgUtil::Int32ToString(ctype, sNum);
+                prefix += sNum;
+                prefix += L"_offset";
+                MgUtil::Int32ToString(offset, sNum);
+                prefix += sNum;
+
+                STRING fileNamePNG = prefix;
+                fileNamePNG += L"_16x16_PNG.png";
+                Ptr<MgByteReader> rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Png, 4, offset);
+                Ptr<MgByteSink> sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG);
+
+                STRING fileNamePNG8 = prefix;
+                fileNamePNG8 += L"_16x16_PNG8.png";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Png8, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG8);
+
+                STRING fileNameJPG = prefix;
+                fileNameJPG += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Jpeg, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameJPG);
+
+                STRING fileNameGIF = prefix;
+                fileNameGIF += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Gif, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameGIF);
+            }
+            rulesProcessed += rules;
+        }
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestMappingService::TestCase_GetLegendImageCompositeThemedConvenience()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map = new MgMap(m_siteConnection);
+        map->Create(mapres, L"TestCase_GetLegendImageCompositeThemedConvenience");
+
+        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
+        Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource);
+        layer->SetName(L"TestCase_GetLegendImageCompositeThemedConvenience");
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+
+        Ptr<MgIntCollection> types = layer->GetGeometryTypeStyles(10000.0);
+        CPPUNIT_ASSERT(3 == types->GetCount());
+        CPPUNIT_ASSERT(types->IndexOf(1) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(2) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(3) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(4) >= 0);
+        for (INT32 i = 0; i < types->GetCount(); i++)
+        {
+            CPPUNIT_ASSERT(4 == types->GetItem(i));
+        }
+
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 3));
+        CPPUNIT_ASSERT(1 == layer->GetThemeCategoryCount(10000.0, 4));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 0));
+        CPPUNIT_ASSERT(3 == layer->GetCompositeThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetCompositeThemeCategoryCount(10000.0, 3));
+
+        INT32 rulesProcessed = 0;
+        for (INT32 ctype = 0; ctype < 3; ctype++)
+        {
+            INT32 rules = layer->GetCompositeThemeCategoryCount(10000.0, ctype);
+            for (INT32 offset = rulesProcessed; offset < (rulesProcessed + rules); offset++)
+            {
+                STRING prefix = L"../UnitTestFiles/GenerateLegendImageConvenience_MultiCTSWithTheme_type";
+                STRING sType;
+                MgUtil::Int32ToString(ctype, sType);
+                prefix += sType;
+                prefix += L"_offset";
+                STRING sOffset;
+                MgUtil::Int32ToString(offset, sOffset);
+                prefix += sOffset;
+
+                STRING fileNamePNG = prefix;
+                fileNamePNG += L"_16x16_PNG.png";
+                Ptr<MgByteReader> rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Png, 4, offset);
+                Ptr<MgByteSink> sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG);
+
+                STRING fileNamePNG8 = prefix;
+                fileNamePNG8 += L"_16x16_PNG8.png";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Png8, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG8);
+
+                STRING fileNameJPG = prefix;
+                fileNameJPG += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Jpeg, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameJPG);
+
+                STRING fileNameGIF = prefix;
+                fileNameGIF += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, MgImageFormats::Gif, 4, offset);
+                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameGIF);
+            }
+            rulesProcessed += rules;
+        }
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 void TestMappingService::TestCase_GetLegendImagePointStyleWithConstRotationsConvenience()
 {
     try

Modified: sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h
===================================================================
--- sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h	2014-06-26 15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h	2014-06-27 09:35:56 UTC (rev 8267)
@@ -37,6 +37,8 @@
     CPPUNIT_TEST(TestCase_GetLegendImage);
     CPPUNIT_TEST(TestCase_GetLegendImagePointStyleWithConstRotations);
     CPPUNIT_TEST(TestCase_GetLegendImageConvenience);
+    CPPUNIT_TEST(TestCase_GetLegendImageCompositeConvenience);
+    CPPUNIT_TEST(TestCase_GetLegendImageCompositeThemedConvenience);
     CPPUNIT_TEST(TestCase_GetLegendImagePointStyleWithConstRotationsConvenience);
     CPPUNIT_TEST(TestCase_CreateRuntimeMap);
     CPPUNIT_TEST(TestCase_DescribeRuntimeMap);
@@ -70,6 +72,8 @@
     void TestCase_GetLegendImage();
     void TestCase_GetLegendImagePointStyleWithConstRotations();
     void TestCase_GetLegendImageConvenience();
+    void TestCase_GetLegendImageCompositeConvenience();
+    void TestCase_GetLegendImageCompositeThemedConvenience();
     void TestCase_GetLegendImagePointStyleWithConstRotationsConvenience();
     void TestCase_QueryFeaturesImageMap();
 



More information about the mapguide-commits mailing list