[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