[mapguide-commits] r9187 - in sandbox/jng/utfgrid: Common/Renderers Server/src/Services/Rendering

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue May 2 07:48:29 PDT 2017


Author: jng
Date: 2017-05-02 07:48:29 -0700 (Tue, 02 May 2017)
New Revision: 9187

Modified:
   sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp
   sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h
   sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp
   sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h
   sandbox/jng/utfgrid/Server/src/Services/Rendering/ServerRenderingService.cpp
Log:
Implement first cut of UTFGrid tile content assembly
 - Ensure color "pixels" are encoded when rendering. The default fill "pixel" is already pre-encoded to 32 (the ' ' character)
 - Change UTFGridContent::AddFeature to return bool to indicate if this feature should be rendered. 
   - Store the return value in a m_renderThisFeature member of UTFGridRenderer
     - Have all ProcessXXX methods return immediately if m_renderThisFeature is false
   - If it should be rendered, the feature will be encoded to a JSON string keyed on the encoded key of the feature (via the same KeyEncode used to compute selection ids)
 - Fix incorrect UTFGrid id encoding/decoding
 - Implement rendering of the keys and data section and the process of stringing all the parts together

Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp	2017-05-02 11:46:23 UTC (rev 9186)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp	2017-05-02 14:48:29 UTC (rev 9187)
@@ -1,6 +1,7 @@
 #include "UTFGridContent.h"
 #include "UnicodeString.h"
 #include "agg_utfgrid_context.h"
+#include "KeyEncode.h"
 
 UTFGridContent::UTFGridContent()
 {
@@ -13,31 +14,138 @@
 std::string UTFGridContent::GetString()
 {
     std::string mbContent;
-    std::wstring content = m_content.str();
-    UnicodeString::WideCharToMultiByte(content.c_str(), mbContent);
+    UnicodeString::WideCharToMultiByte(m_content.str().c_str(), mbContent);
     return mbContent;
 }
 
-void UTFGridContent::AddFeature(unsigned int color, RS_FeatureReader* feature)
+bool UTFGridContent::AddFeature(unsigned int color, RS_FeatureReader* feature)
 {
-    
+    static const size_t MAX_STRING = 64;
+
+    std::string key = m_keyEncode.EncodeKey(feature);
+    //No key, not selectable. Not selectable, don't bother encoding.
+    if (!key.empty() && m_features.find(key) == m_features.end())
+    {
+        std::wstring wVal = L"{";
+
+        bool bFirst = true;
+        int count = 0;
+        auto propNames = feature->GetIdentPropNames(count);
+        for (int i = 0; i < count; i++)
+        {
+            if (!bFirst)
+            {
+                wVal.append(L",");
+            }
+
+            auto propName = propNames[i];
+            auto propVal = feature->GetAsString(propName);
+
+            wVal.append(L"\"");
+            wVal.append(propName);
+            wVal.append(L"\": ");
+
+            auto propType = feature->GetPropertyType(propName);
+            if (propType == FdoDataType_String || propType == FdoDataType_DateTime)
+            {
+                wVal.append(L"\"");
+                wVal.append(propVal);
+                wVal.append(L"\"");
+            }
+            else 
+            {
+                wVal.append(propVal);
+            }
+        }
+
+        wVal += L"}";
+
+        m_features.insert(std::make_pair(key, wVal));
+        m_pixels.insert(std::make_pair(color, key));
+        return true;
+    }
+    return false;
 }
 
-void UTFGridContent::StartGridRow()
+void UTFGridContent::StartGrid()
 {
+    m_content << "{" << std::endl << "  \"grid\": [" << std::endl;
+}
 
+void UTFGridContent::StartGridRow(bool bFirst)
+{
+    if (bFirst)
+        m_content << "    \"";
+    else
+        m_content << "," << std::endl << "    \"";
 }
 
 void UTFGridContent::AppendRowPixel(unsigned int pixel)
 {
-    m_content.sputc(EncodeChar(pixel));
+    m_trackedColors.insert(pixel);
+    m_content << (wchar_t)pixel;
 }
 
 void UTFGridContent::EndGridRow()
 {
-    m_content.sputc('\n');
+    m_content << "\"";
 }
 
+void UTFGridContent::EndGrid()
+{
+    m_content << std::endl << "  ]";
+}
+
+void UTFGridContent::WriteKeys()
+{
+    m_content << "," << std::endl;
+    m_content << "  \"keys\": [" << std::endl;
+    for (auto it = m_trackedColors.begin(); it != m_trackedColors.end(); it++)
+    {
+        if (it != m_trackedColors.begin())
+            m_content << "," << std::endl;
+
+        if (*it == 32) // This is the "empty space" pixel
+        {
+            m_content << "    \"\"";
+        }
+        else
+        {
+            auto decodedKey = DecodeChar(*it);
+            m_content << "    \"" << decodedKey << "\"";
+        }
+    }
+    m_content << std::endl << "  ]";
+}
+
+void UTFGridContent::WriteData()
+{
+    m_content << "," << std::endl;
+    m_content << "  \"data\": {" << std::endl;
+    bool bFirst = true;
+    for (auto it = m_trackedColors.begin(); it != m_trackedColors.end(); it++)
+    {
+        if (*it == 32) // This is the "empty space" pixel
+        {
+            continue;
+        }
+
+        auto colorKey = DecodeChar(*it);
+        if (m_pixels.find(colorKey) != m_pixels.end())
+        {
+            auto featKey = m_pixels[colorKey];
+            auto featData = m_features[featKey];
+            if (!bFirst)
+                m_content << "," << std::endl;
+
+            m_content << "    \"" << colorKey << "\": " << featData;
+            bFirst = false;
+        }
+    }
+    m_content << std::endl << "  }" << std::endl; //End data
+    m_content << "}"; //End UTFGrid
+}
+
 unsigned int UTFGridContent::EncodeChar(unsigned int toEncode)
 {
     // Encoding IDs: https://github.com/mapbox/utfgrid-spec/blob/master/1.3/utfgrid.md#encoding-ids
@@ -49,8 +157,8 @@
     {
         encoded += 1;
     }
-    // If result is <= 92, add 1
-    if (encoded <= 92)
+    // If result is >= 92, add 1
+    if (encoded >= 92)
     {
         encoded += 1;
     }
@@ -67,8 +175,8 @@
     {
         decoded -= 1;
     }
-    // If codepoint is <= 35, subtract 1
-    if (decoded <= 35)
+    // If codepoint is >= 35, subtract 1
+    if (decoded >= 35)
     {
         decoded -= 1;
     }

Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h	2017-05-02 11:46:23 UTC (rev 9186)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h	2017-05-02 14:48:29 UTC (rev 9187)
@@ -20,9 +20,12 @@
 
 #include "Renderers.h"
 #include "RS_FeatureReader.h"
+#include "KeyEncode.h"
+#include <set>
 #include <sstream>
 
-typedef std::map<unsigned int, std::string> FeaturePixelMap;
+typedef std::map<unsigned int, std::string> ColorKeyMap;
+typedef std::map<std::string, std::wstring> KeyFeatureMap;
 
 class UTFGridContent
 {
@@ -32,18 +35,28 @@
 
     RENDERERS_API std::string GetString();
 
-    void AddFeature(unsigned int color, RS_FeatureReader* feature);
+    bool AddFeature(unsigned int color, RS_FeatureReader* feature);
 
-    void StartGridRow();
+    void StartGrid();
+    void StartGridRow(bool bFirst);
     void AppendRowPixel(unsigned int pixel);
     void EndGridRow();
+    void EndGrid();
 
-private:
+    void WriteKeys();
+    void WriteData();
+
     static unsigned int EncodeChar(unsigned int toEncode);
     static unsigned int DecodeChar(unsigned int toDecode);
 
-    std::wstringbuf m_content;
-    FeaturePixelMap m_features;
+private:
+
+    std::wstringstream m_content;
+    std::set<unsigned int> m_trackedColors;
+
+    KeyFeatureMap m_features;
+    ColorKeyMap m_pixels;
+    KeyEncode m_keyEncode;
 };
 
 #endif
\ No newline at end of file

Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp	2017-05-02 11:46:23 UTC (rev 9186)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp	2017-05-02 14:48:29 UTC (rev 9187)
@@ -35,9 +35,12 @@
 // StartMap
 //    StartLayer
 //        StartFeature
+//           - Reset renderme flag to true
 //           - Allocate a "color" (an incrementing unsigned int)
 //           - Encode current feature attributes to UTFGridContent and associate it with the color
+//           - Set renderme flag to true if feature encoding was successful
 //           Service ProcessXXX calls from the Stylizer
+//              - Ignore call if renderme == false
 //              - Render each geometry into the agg_utfgrid_context
 //    EndLayer
 // EndMap
@@ -55,7 +58,8 @@
     m_mapScale(0.0),
     m_mapInfo(NULL),
     m_layerInfo(NULL),
-    m_fcInfo(NULL)
+    m_fcInfo(NULL),
+    m_renderThisFeature(true)
 {
     // get the agg context going
     m_context = new agg_utfgrid_context(UTF_GRID_WIDTH, UTF_GRID_HEIGHT, resolution);
@@ -111,17 +115,24 @@
 void UTFGridRenderer::EndMap()
 {
     m_mapInfo = NULL;
+
+    m_content->StartGrid();
+    bool bFirst = true;
     //Y-axis is flipped, so reverse iterate the y-axis
     for (int y = m_context->rendering_buffer.height() - 1; y >= 0; y--)
     {
-        m_content->StartGridRow();
+        m_content->StartGridRow(bFirst);
         auto row_ptr = m_context->rendering_buffer.row_ptr(y);
         for (int x = 0; x < m_context->rendering_buffer.width(); x++)
         {
             m_content->AppendRowPixel(row_ptr[x]);
         }
         m_content->EndGridRow();
+        bFirst = false;
     }
+    m_content->EndGrid();
+    m_content->WriteKeys();
+    m_content->WriteData();
 }
 
 void UTFGridRenderer::StartLayer(RS_LayerUIInfo * layerInfo, RS_FeatureClassInfo * classInfo)
@@ -140,17 +151,24 @@
 
 void UTFGridRenderer::StartFeature(RS_FeatureReader * feature, bool /* initialPass */, const RS_String * /* tooltip */, const RS_String * /* url */, const RS_String * /* theme */, double /* zOffset */, double /* zExtrusion */, RS_ElevationType /* zOffsetType */)
 {
-    m_currentColor++;
-    m_content->AddFeature(m_currentColor, feature);
+    m_renderThisFeature = m_content->AddFeature(m_currentColor, feature);
+    if (m_renderThisFeature)
+        m_currentColor++;
 }
 
 void UTFGridRenderer::ProcessPolygon(LineBuffer * lb, RS_FillStyle & fill)
 {
+    if (!m_renderThisFeature)
+        return;
+
     DrawScreenPolygon(lb, &m_xform, fill.color().argb());
 }
 
 void UTFGridRenderer::ProcessPolyline(LineBuffer * lb, RS_LineStroke & /*lsym*/)
 {
+    if (!m_renderThisFeature)
+        return;
+
     DrawScreenPolyline(lb, &m_xform, m_lineStroke);
 }
 
@@ -161,6 +179,9 @@
 
 void UTFGridRenderer::ProcessMarker(LineBuffer * srclb, RS_MarkerDef & mdef, bool allowOverpost, RS_Bounds * /*bounds*/)
 {
+    if (!m_renderThisFeature)
+        return;
+
     for (int i = 0; i<srclb->point_count(); ++i)
     {
         // if marker is processed from here it should be added to the
@@ -496,7 +517,7 @@
     c->rasterizer.add_path(stroke);
     c->rasterizer.filling_rule(agg::fill_non_zero);
 
-    c->renderer_scanline.color(utfpix32(lineStroke.color));
+    c->renderer_scanline.color(utfpix32(UTFGridContent::EncodeChar(lineStroke.color)));
     agg::render_scanlines(c->rasterizer, c->scanline_utf, c->renderer_scanline);
 
     c->rasterizer.filling_rule(agg::fill_even_odd);
@@ -517,7 +538,7 @@
         m_context->rasterizer.reset();
         m_context->rasterizer.add_path(m_context->ps, pathids[i]);
 
-        m_context->renderer_scanline.color(utfpix32(m_currentColor));
+        m_context->renderer_scanline.color(utfpix32(UTFGridContent::EncodeChar(m_currentColor)));
         agg::render_scanlines(m_context->rasterizer, m_context->scanline_utf, m_context->renderer_scanline);
     }
 }

Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h	2017-05-02 11:46:23 UTC (rev 9186)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h	2017-05-02 14:48:29 UTC (rev 9187)
@@ -108,6 +108,8 @@
     SE_LineStroke m_lineStroke;
 
     UTFGridContent* m_content;
+
+    bool m_renderThisFeature;
 };
 
 #endif
\ No newline at end of file

Modified: sandbox/jng/utfgrid/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- sandbox/jng/utfgrid/Server/src/Services/Rendering/ServerRenderingService.cpp	2017-05-02 11:46:23 UTC (rev 9186)
+++ sandbox/jng/utfgrid/Server/src/Services/Rendering/ServerRenderingService.cpp	2017-05-02 14:48:29 UTC (rev 9187)
@@ -615,8 +615,7 @@
     std::string utfgrid = content.GetString();
     Ptr<MgByteSource> bs = new MgByteSource((BYTE_ARRAY_IN)utfgrid.c_str(), (INT32)utfgrid.length());
 
-    // TODO: Convert to MgMimeType::Json when encoding is fully implemented
-    bs->SetMimeType(MgMimeType::Text);
+    bs->SetMimeType(MgMimeType::Json);
 
     ret = bs->GetReader();
 



More information about the mapguide-commits mailing list