[mapguide-commits] r9182 - sandbox/jng/utfgrid/Common/Renderers
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Mon May 1 08:51:03 PDT 2017
Author: jng
Date: 2017-05-01 08:51:03 -0700 (Mon, 01 May 2017)
New Revision: 9182
Added:
sandbox/jng/utfgrid/Common/Renderers/MapUTFGrid.h
sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp
sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h
sandbox/jng/utfgrid/Common/Renderers/agg_utfgrid_context.h
Modified:
sandbox/jng/utfgrid/Common/Renderers/Makefile.am
sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj
sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj.filters
sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp
sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h
Log:
Initial implementation of UTFGridRenderer
- Add maputfgrid.h from mapserver, as it already implements the low-level AGG pixel format primitive (utfpix32) for UTFGrid rendering
- Add agg_utfgrid_context. This is like agg_context, but uses agg template specializations for the above utfpix32 and eliminates AGG rendering stuff relating to alpha masking and font management.
- Copy the bulk of the Marker/Polygon/Polyline (and any required support code) from the AGGRenderer, except instead of using agg_context, it uses the agg_utfgrid_context.
- Add skeleton UTFGridContent which is focused on the actual assembly of the UTFGrid tile. This class is analogous to KmlContent (wrt KmlRenderer).
Modified: sandbox/jng/utfgrid/Common/Renderers/Makefile.am
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/Makefile.am 2017-04-27 12:44:20 UTC (rev 9181)
+++ sandbox/jng/utfgrid/Common/Renderers/Makefile.am 2017-05-01 15:51:03 UTC (rev 9182)
@@ -41,6 +41,8 @@
RenderUtil.cpp \
RS_ByteData.cpp \
SymbolTrans.cpp \
+ UTFGridRenderer.cpp \
+ UTFGridContent.cpp \
W2DRewriter.cpp \
complex_polygon_gd.cpp
@@ -48,6 +50,7 @@
AGGRenderer.h \
AGGImageIO.h \
agg_context.h \
+ agg_utfgrid_context.h \
agg_mg_overloads.h \
AGGW2DRewriter.h \
AGGFillPatterns.h \
@@ -66,6 +69,7 @@
KmlIconStyle.h \
KmlRenderer.h \
MapQuantization.h \
+ MapUTFGrid.h \
ObservationMesh.h \
Renderers.h \
RenderUtil.h \
@@ -74,6 +78,8 @@
RSDWFOutputStream.h \
stdafx.h \
SymbolTrans.h \
+ UTFGridRenderer.h \
+ UTFGridContent.h \
W2DRewriter.h \
whip_fill_library.h \
whip_hatch_library.h \
Added: sandbox/jng/utfgrid/Common/Renderers/MapUTFGrid.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/MapUTFGrid.h (rev 0)
+++ sandbox/jng/utfgrid/Common/Renderers/MapUTFGrid.h 2017-05-01 15:51:03 UTC (rev 9182)
@@ -0,0 +1,249 @@
+/******************************************************************************
+* Adapted for use in MgRenderers by Jackie Ng
+*
+* $Id$
+*
+* Project: MapServer
+* Purpose: UTFGrid rendering functions (using AGG)
+* Author: Francois Desjarlais
+*
+******************************************************************************
+* Copyright (c) 1996-2007 Regents of the University of Minnesota.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies of this Software or works derived from this Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*****************************************************************************/
+#ifndef _MAPUTFGRID_H_
+#define _MAPUTFGRID_H_
+
+#include "agg_renderer_base.h"
+#include "agg_rendering_buffer.h"
+
+/*
+* Using AGG templates to create UTFGrid pixel.
+*/
+
+//==================================================================utfpix32
+struct utfpix32
+{
+ typedef agg::int32u value_type;
+ typedef agg::int64u calc_type;
+ typedef agg::int64 long_type;
+
+ typedef utfpix32 self_type;
+
+ value_type v;
+
+ //--------------------------------------------------------------------
+ utfpix32() {}
+
+ //--------------------------------------------------------------------
+ utfpix32(unsigned v_) :
+ v(agg::int32u(v_)) {}
+
+ //--------------------------------------------------------------------
+ utfpix32(const self_type& c) :
+ v(c.v) {}
+
+ //--------------------------------------------------------------------
+ void clear()
+ {
+ v = 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ *this = c;
+ }
+};
+
+//=================================================pixfmt_utf
+template<class ColorT, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
+class pixfmt_utf
+{
+public:
+ typedef RenBuf rbuf_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ pix_width = sizeof(value_type),
+ pix_step = Step,
+ pix_offset = Offset
+ };
+
+private:
+ //--------------------------------------------------------------------
+ static AGG_INLINE void copy_or_blend_pix(value_type* p,
+ const color_type& c,
+ unsigned cover)
+ {
+ *p = c.v;
+ }
+
+ static AGG_INLINE void copy_or_blend_pix(value_type* p,
+ const color_type& c)
+ {
+ *p = c.v;
+ }
+
+public:
+ pixfmt_utf() : m_rbuf(0) {}
+ //--------------------------------------------------------------------
+ explicit pixfmt_utf(rbuf_type& rb) :
+ m_rbuf(&rb)
+ {}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
+ //--------------------------------------------------------------------
+
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
+ {
+ agg::rect_i r(x1, y1, x2, y2);
+ if (r.clip(agg::rect_i(0, 0, pixf.width() - 1, pixf.height() - 1)))
+ {
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE unsigned width() const { return m_rbuf->width(); }
+ AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
+
+ //--------------------------------------------------------------------
+ agg::int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ const agg::int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ row_data row(int y) const { return m_rbuf->row(y); }
+
+ const agg::int8u* pix_ptr(int x, int y) const
+ {
+ return m_rbuf->row_ptr(y) + x * Step + Offset + 1213;
+ }
+
+ agg::int8u* pix_ptr(int x, int y)
+ {
+ return m_rbuf->row_ptr(y) + x * Step + Offset + 1213;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE static void make_pix(agg::int8u* p, const color_type& c)
+ {
+ *(value_type*)p = c.v;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE color_type pixel(int x, int y) const
+ {
+ value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
+ return color_type(*p);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
+ {
+ *((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_pixel(int x, int y, const color_type& c, agg::int8u cover)
+ {
+ copy_or_blend_pix((value_type*)
+ m_rbuf->row_ptr(x, y, 1) + x * Step + Offset,
+ c);
+ }
+
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_hline(int x, int y,
+ unsigned len,
+ const color_type& c)
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
+ do
+ {
+ *p = c.v;
+ p += Step;
+ } while (--len);
+ }
+
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_vline(int x, int y,
+ unsigned len,
+ const color_type& c)
+ {
+ do
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
+ *p = c.v;
+ } while (--len);
+ }
+
+
+ //--------------------------------------------------------------------
+ void blend_hline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ agg::int8u cover)
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
+ do
+ {
+ *p = c.v;
+ p += Step;
+ } while (--len);
+ }
+
+
+ //--------------------------------------------------------------------
+ void blend_vline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ agg::int8u cover)
+ {
+ do
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
+ *p = c.v;
+ } while (--len);
+ }
+
+
+private:
+ rbuf_type* m_rbuf;
+};
+
+#endif
\ No newline at end of file
Modified: sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj 2017-04-27 12:44:20 UTC (rev 9181)
+++ sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj 2017-05-01 15:51:03 UTC (rev 9182)
@@ -218,6 +218,7 @@
<ClCompile Include="SymbolTrans.cpp" />
<ClCompile Include="DWFRenderer.cpp" />
<ClCompile Include="EPlotRenderer.cpp" />
+ <ClCompile Include="UTFGridContent.cpp" />
<ClCompile Include="UTFGridRenderer.cpp" />
<ClCompile Include="W2DRewriter.cpp" />
<ClCompile Include="complex_polygon_gd.cpp" />
@@ -259,13 +260,16 @@
<ClCompile Include="RenderUtil.cpp" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="agg_utfgrid_context.h" />
<ClInclude Include="MapQuantization.h" />
+ <ClInclude Include="MapUTFGrid.h" />
<ClInclude Include="SymbolTrans.h" />
<ClInclude Include="DWFRenderer.h" />
<ClInclude Include="DWFRSInputStream.h" />
<ClInclude Include="EPlotRenderer.h" />
<ClInclude Include="RSDWFInputStream.h" />
<ClInclude Include="RSDWFOutputStream.h" />
+ <ClInclude Include="UTFGridContent.h" />
<ClInclude Include="UTFGridRenderer.h" />
<ClInclude Include="W2DRewriter.h" />
<ClInclude Include="whip_fill_library.h" />
Modified: sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj.filters
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj.filters 2017-04-27 12:44:20 UTC (rev 9181)
+++ sandbox/jng/utfgrid/Common/Renderers/Renderers.vcxproj.filters 2017-05-01 15:51:03 UTC (rev 9182)
@@ -120,6 +120,9 @@
<ClCompile Include="UTFGridRenderer.cpp">
<Filter>UTFGridRenderer</Filter>
</ClCompile>
+ <ClCompile Include="UTFGridContent.cpp">
+ <Filter>UTFGridRenderer</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SymbolTrans.h">
@@ -214,6 +217,15 @@
<ClInclude Include="UTFGridRenderer.h">
<Filter>UTFGridRenderer</Filter>
</ClInclude>
+ <ClInclude Include="UTFGridContent.h">
+ <Filter>UTFGridRenderer</Filter>
+ </ClInclude>
+ <ClInclude Include="agg_utfgrid_context.h">
+ <Filter>UTFGridRenderer</Filter>
+ </ClInclude>
+ <ClInclude Include="MapUTFGrid.h">
+ <Filter>UTFGridRenderer</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Renderers.rc" />
Added: sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp (rev 0)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.cpp 2017-05-01 15:51:03 UTC (rev 9182)
@@ -0,0 +1,73 @@
+#include "UTFGridContent.h"
+#include "agg_utfgrid_context.h"
+
+UTFGridContent::UTFGridContent()
+{
+}
+
+UTFGridContent::~UTFGridContent()
+{
+}
+
+std::string UTFGridContent::GetString()
+{
+ return m_content.str();
+}
+
+void UTFGridContent::AddFeature(unsigned int color, RS_FeatureReader* feature)
+{
+
+}
+
+void UTFGridContent::StartGridRow()
+{
+
+}
+
+void UTFGridContent::AppendRowPixel(utfgrid_band_type pixel)
+{
+ m_content.sputc(EncodeChar(pixel));
+}
+
+void UTFGridContent::EndGridRow()
+{
+ m_content.sputc('\n');
+}
+
+utfgrid_band_type UTFGridContent::EncodeChar(utfgrid_band_type toEncode)
+{
+ // Encoding IDs: https://github.com/mapbox/utfgrid-spec/blob/master/1.3/utfgrid.md#encoding-ids
+
+ // Add 32
+ utfgrid_band_type encoded = toEncode + 32;
+ // If result is >= 34, add 1
+ if (encoded >= 34)
+ {
+ encoded += 1;
+ }
+ // If result is <= 92, add 1
+ if (encoded <= 92)
+ {
+ encoded += 1;
+ }
+ return encoded;
+}
+
+utfgrid_band_type UTFGridContent::DecodeChar(utfgrid_band_type toDecode)
+{
+ // Decoding IDs: https://github.com/mapbox/utfgrid-spec/blob/master/1.3/utfgrid.md#encoding-ids
+
+ // If codepoint is >= 93, subtract 1
+ utfgrid_band_type decoded = toDecode;
+ if (decoded >= 93)
+ {
+ decoded -= 1;
+ }
+ // If codepoint is <= 35, subtract 1
+ if (decoded <= 35)
+ {
+ decoded -= 1;
+ }
+ // Subtract 32
+ return decoded - 32;
+}
\ No newline at end of file
Added: sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h (rev 0)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridContent.h 2017-05-01 15:51:03 UTC (rev 9182)
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _UTFGRIDCONTENT_H_
+#define _UTFGRIDCONTENT_H_
+
+#include "Renderers.h"
+#include "RS_FeatureReader.h"
+#include "agg_utfgrid_context.h"
+#include <sstream>
+
+typedef std::map<unsigned int, std::string> FeaturePixelMap;
+
+class UTFGridContent
+{
+public:
+ RENDERERS_API UTFGridContent();
+ RENDERERS_API ~UTFGridContent();
+
+ RENDERERS_API std::string GetString();
+
+ void AddFeature(unsigned int color, RS_FeatureReader* feature);
+
+ void StartGridRow();
+ void AppendRowPixel(utfgrid_band_type pixel);
+ void EndGridRow();
+
+private:
+ static utfgrid_band_type EncodeChar(utfgrid_band_type toEncode);
+ static utfgrid_band_type DecodeChar(utfgrid_band_type toDecode);
+
+ std::stringbuf m_content;
+ FeaturePixelMap m_features;
+};
+
+#endif
\ No newline at end of file
Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp 2017-04-27 12:44:20 UTC (rev 9181)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.cpp 2017-05-01 15:51:03 UTC (rev 9182)
@@ -1,18 +1,28 @@
#include "UTFGridRenderer.h"
+#include "UtfGridContent.h"
+#include "SLDSymbols.h"
+#include "SymbolTrans.h"
+#include "agg_utfgrid_context.h"
-#define UTF_GRID_WIDTH 256
-#define UTF_GRID_HEIGHT 256
+UTFGridRenderer::UTFGridRenderer(UTFGridContent* utfGrid)
+ : m_currentColor(0),
+ m_content(utfGrid)
+{
+ // allocate back buffer
+ int len = UTF_GRID_WIDTH * UTF_GRID_HEIGHT;
+ m_rows = new unsigned int[len];
-UTFGridRenderer::UTFGridRenderer()
-{
+ // get the agg context going
+ m_context = new agg_utfgrid_context(m_rows, UTF_GRID_WIDTH, UTF_GRID_HEIGHT);
}
-
UTFGridRenderer::~UTFGridRenderer()
{
+ delete m_context;
+ delete[] m_rows;
}
-void UTFGridRenderer::StartMap(RS_MapUIInfo * mapInfo, RS_Bounds & extents, double mapScale, double dpi, double metersPerUnit, CSysTransformer * xformToLL)
+void UTFGridRenderer::StartMap(RS_MapUIInfo * mapInfo, RS_Bounds & extents, double mapScale, double dpi, double metersPerUnit, CSysTransformer * /*xformToLL*/)
{
m_mapScale = mapScale;
m_dpi = dpi;
@@ -57,6 +67,16 @@
void UTFGridRenderer::EndMap()
{
m_mapInfo = NULL;
+ for (int y = 0; y < UTF_GRID_HEIGHT; y++)
+ {
+ m_content->StartGridRow();
+ auto row_ptr = m_context->rendering_buffer.row_ptr(y);
+ for (int x = 0; x < UTF_GRID_WIDTH; x++)
+ {
+ m_content->AppendRowPixel(row_ptr[x]);
+ }
+ m_content->EndGridRow();
+ }
}
void UTFGridRenderer::StartLayer(RS_LayerUIInfo * layerInfo, RS_FeatureClassInfo * classInfo)
@@ -73,9 +93,10 @@
m_fcInfo = NULL;
}
-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)
+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_currentFeature = feature;
+ m_currentColor++;
+ m_content->AddFeature(m_currentColor, feature);
}
void UTFGridRenderer::ProcessPolygon(LineBuffer * lb, RS_FillStyle & fill)
@@ -83,32 +104,37 @@
DrawScreenPolygon(lb, &m_xform, fill.color().argb());
}
-void UTFGridRenderer::ProcessPolyline(LineBuffer * lb, RS_LineStroke & lsym)
+void UTFGridRenderer::ProcessPolyline(LineBuffer * lb, RS_LineStroke & /*lsym*/)
{
DrawScreenPolyline(lb, &m_xform, m_lineStroke);
}
-void UTFGridRenderer::ProcessRaster(unsigned char * data, int length, RS_ImageFormat format, int width, int height, RS_Bounds & extents, TransformMesh * xformMesh)
+void UTFGridRenderer::ProcessRaster(unsigned char * /*data*/, int /*length*/, RS_ImageFormat /*format*/, int /*width*/, int /*height*/, RS_Bounds & /*extents*/, TransformMesh * /*xformMesh*/)
{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::ProcessMarker(LineBuffer * lb, RS_MarkerDef & mdef, bool allowOverpost, RS_Bounds * bounds)
+void UTFGridRenderer::ProcessMarker(LineBuffer * srclb, RS_MarkerDef & mdef, bool allowOverpost, RS_Bounds * /*bounds*/)
{
-
+ for (int i = 0; i<srclb->point_count(); ++i)
+ {
+ // if marker is processed from here it should be added to the
+ // feature W2D, not the labeling W2D - need the API to reflect that.
+ ProcessOneMarker(srclb->x_coord(i), srclb->y_coord(i), mdef, allowOverpost);
+ }
}
-void UTFGridRenderer::ProcessLabelGroup(RS_LabelInfo * labels, int nlabels, const RS_String & text, RS_OverpostType type, bool exclude, LineBuffer * path, double scaleLimit)
+void UTFGridRenderer::ProcessLabelGroup(RS_LabelInfo * /*labels*/, int /*nlabels*/, const RS_String & /*text*/, RS_OverpostType /*type*/, bool /*exclude*/, LineBuffer * /*path*/, double /*scaleLimit*/)
{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::AddDWFContent(RS_InputStream * in, CSysTransformer * xformer, const RS_String & section, const RS_String & passwd, const RS_String & w2dfilter)
+void UTFGridRenderer::AddDWFContent(RS_InputStream * /*in*/, CSysTransformer * /*xformer*/, const RS_String & /*section*/, const RS_String & /*passwd*/, const RS_String & /*w2dfilter*/)
{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::SetSymbolManager(RS_SymbolManager * manager)
+void UTFGridRenderer::SetSymbolManager(RS_SymbolManager * /*manager*/)
{
//Not applicable for UTFGrid
}
@@ -168,25 +194,300 @@
return false;
}
-void UTFGridRenderer::DrawScreenPolyline(LineBuffer * polyline, const SE_Matrix * xform, const SE_LineStroke & lineStroke)
+void UTFGridRenderer::ProcessOneMarker(double x, double y, RS_MarkerDef& mdef, bool /*allowOverpost*/)
{
+ // symbol in mapping space units
+ double iw = _MeterToMapSize(mdef.units(), mdef.width());
+ double ih = _MeterToMapSize(mdef.units(), mdef.height());
+
+ // unrotated symbol bounding box (mapping space)
+ RS_Bounds dst(x, y, x + iw, y + ih);
+
+ // convert to pixel size
+ iw *= m_xform.x0;
+ ih *= m_xform.y1;
+
+ // if it's too big, make it smaller
+ // it cannot be too big since we allocate 4*iw*ih bytes of
+ // memory to cache the symbol image - this code simply truncates
+ // the size, ignoring changes in aspect ratio
+ const double MAX_SIZE = 4096.0;
+ if (iw > MAX_SIZE)
+ {
+ iw = MAX_SIZE;
+ dst.maxx = dst.minx + iw * m_ixform.x0;
+ }
+ if (ih > MAX_SIZE)
+ {
+ ih = MAX_SIZE;
+ dst.maxy = dst.miny + ih * m_ixform.y1;
+ }
+
+ // get insertion point
+ double refX = mdef.insx();
+ double refY = mdef.insy();
+
+ // rotation angle
+ double angleRad = mdef.rotation() * M_PI180;
+
+ // Unlike the AGGRenderer, we will just render an SLD_CIRCLE for this marker. We're not rendering
+ // actual pixels with this renderer, just characters, so we can afford some leeway to ensure we can
+ // get an adequate "hit area" for point features
+ RS_F_Point* poly = (RS_F_Point*)SLD_CIRCLE;
+ int npts = sizeof(SLD_CIRCLE) / (2 * sizeof(double));
+
+ // construct transformer
+ RS_Bounds src(0.0, 0.0, 1.0, 1.0);
+ SymbolTrans trans(src, dst, refX, refY, angleRad);
+
+ // transform to coordinates of temporary image where we
+ // draw symbol before transfering to the map
+ LineBuffer* lb = LineBufferPool::NewLineBuffer(m_pPool, 8);
+ std::auto_ptr<LineBuffer> spLB(lb);
+
+ double tempx, tempy;
+ for (int i = 0; i<npts; ++i)
+ {
+ tempx = poly[i].x;
+ tempy = poly[i].y;
+
+ // unit square to world
+ trans.TransformPoint(tempx, tempy);
+
+ WorldToScreenPoint(tempx, tempy, tempx, tempy);
+
+ if (i)
+ lb->LineTo(tempx, tempy);
+ else
+ lb->MoveTo(tempx, tempy);
+ }
+
+ // unknown symbol
+ m_lineStroke.color = m_currentColor;
+ m_lineStroke.weight = 1.0;
+ DrawScreenPolyline(m_context, lb, NULL, m_lineStroke);
+
+ LineBufferPool::FreeLineBuffer(m_pPool, spLB.release());
}
-void UTFGridRenderer::DrawScreenPolygon(LineBuffer * polygon, const SE_Matrix * xform, unsigned int fill)
+double UTFGridRenderer::_MeterToMapSize(RS_Units unit, double number)
{
+ double scale_factor;
+
+ if (unit == RS_Units_Device) // in meters, fixed size
+ scale_factor = m_mapScale / m_metersPerUnit;
+ else
+ scale_factor = 1.0 / m_metersPerUnit;
+
+ return number * scale_factor;
}
-void UTFGridRenderer::DrawScreenRaster(unsigned char * data, int length, RS_ImageFormat format, int native_width, int native_height, double x, double y, double w, double h, double angleDeg)
+void UTFGridRenderer::_TransferPoints(agg_utfgrid_context* c, LineBuffer* srcLB, const SE_Matrix* xform, unsigned int* pathids)
{
+ c->ps.remove_all();
+
+ int offset = 0;
+ int* cntrs = srcLB->cntrs();
+
+ if (pathids)
+ *pathids = 0;
+
+ for (int h = 0; h<srcLB->geom_count(); ++h)
+ {
+ if (h && pathids)
+ pathids[h] = c->ps.start_new_path();
+
+ int cur_cntr_count = srcLB->geom_size(h);
+
+ for (int i = 0; i<cur_cntr_count; ++i)
+ {
+ int ci = offset;
+
+ // add the initial point
+ double sx = srcLB->x_coord(ci);
+ double sy = srcLB->y_coord(ci);
+ ++ci;
+
+ if (xform)
+ xform->transform(sx, sy, sx, sy);
+
+ c->ps.move_to(sx, sy);
+
+ int ptlast = cntrs[i] - 1;
+ if (!ptlast)
+ continue;
+
+ // add the interior points
+ double tx, ty;
+ for (int j = 1; j<ptlast; ++j)
+ {
+ tx = srcLB->x_coord(ci);
+ ty = srcLB->y_coord(ci);
+ ++ci;
+
+ if (xform)
+ xform->transform(tx, ty, tx, ty);
+
+ c->ps.line_to(tx, ty);
+ }
+
+ // add the final point
+ tx = srcLB->x_coord(ci);
+ ty = srcLB->y_coord(ci);
+ ++ci;
+
+ if (xform)
+ xform->transform(tx, ty, tx, ty);
+
+ // detect a close segment (in a Linebuffer this is caused by first and
+ // last point of the contour being equal and size of contour > 2 points)
+ if (tx == sx && ty == sy && ptlast > 1)
+ c->ps.close_polygon();
+ else if (ptlast == 1)
+ {
+ // only two points in the buffer - check if this corresponds to a dot
+ double dx = tx - sx;
+ double dy = ty - sy;
+ double len2 = dx*dx + dy*dy;
+
+ // Although dots are replaced by lines with length LINE_SEGMENT_DOT_SIZE,
+ // it's possible that the lines end up somewhat larger in the wrapping
+ // case due to warping. We therefore perform the check against a 10 times
+ // larger length. In the future it might be worth relaxing this to simply
+ // check for any segment less than one pixel in length.
+ if (len2 < 100.0*LINE_SEGMENT_DOT_SIZE*LINE_SEGMENT_DOT_SIZE)
+ {
+ // found a dot - draw it as a 1-pixel long line
+ if (len2 > 0.0)
+ {
+ double len = sqrt(len2);
+ dx /= len;
+ dy /= len;
+ c->ps.move_to(tx - 0.5*dx, ty - 0.5*dy);
+ c->ps.line_to(tx + 0.5*dx, ty + 0.5*dy);
+ }
+ else
+ {
+ // length of line can be 0 when DOTS_HATCH is rendered from DWF
+ // so use LINE_SEGMENT_DOT_SIZE to render that dots
+ c->ps.move_to(tx - LINE_SEGMENT_DOT_SIZE, ty - LINE_SEGMENT_DOT_SIZE);
+ c->ps.line_to(tx + LINE_SEGMENT_DOT_SIZE, ty + LINE_SEGMENT_DOT_SIZE);
+ }
+ }
+ else
+ {
+ // a normal line segment
+ c->ps.line_to(tx, ty);
+ }
+ }
+ else
+ c->ps.line_to(tx, ty);
+
+ offset += cntrs[i];
+ }
+
+ cntrs += cur_cntr_count;
+ }
+}
+
+void UTFGridRenderer::DrawScreenPolyline(LineBuffer * srclb, const SE_Matrix * xform, const SE_LineStroke & lineStroke)
+{
+ DrawScreenPolyline(m_context, srclb, xform, lineStroke);
+}
+
+void UTFGridRenderer::DrawScreenPolyline(agg_utfgrid_context* c, LineBuffer* srclb, const SE_Matrix* xform, const SE_LineStroke& lineStroke)
+{
+ // if you have no geoms, why do you call us at all?
+ if (srclb->geom_count() == 0)
+ return;
+
+ double weightpx = rs_max(1.0, lineStroke.weight);
+
+ // add to the agg path storage - here it doesn't matter
+ // how many geometries there are in the line buffer,
+ // so we just pass NULL for the path offsets array
+ _TransferPoints(c, srclb, xform, NULL);
+
+ // stroke the line as a polygon
+ agg::conv_stroke<agg::path_storage> stroke(c->ps);
+ stroke.width(weightpx);
+
+ // set up cap / join style
+ switch (lineStroke.cap)
+ {
+ case SE_LineCap_None:
+ stroke.line_cap(agg::butt_cap);
+ break;
+ case SE_LineCap_Triangle:
+ stroke.line_cap(agg::triangle_cap);
+ break;
+ case SE_LineCap_Square:
+ stroke.line_cap(agg::square_cap);
+ break;
+ case SE_LineCap_Round:
+ default:
+ stroke.line_cap(agg::round_cap);
+ break;
+ }
+
+ switch (lineStroke.join)
+ {
+ case SE_LineJoin_None:
+ stroke.line_join(agg::bevel_join); // AGG doesn't support None
+ break;
+ case SE_LineJoin_Bevel:
+ stroke.line_join(agg::bevel_join);
+ break;
+ case SE_LineJoin_Miter:
+ stroke.line_join(agg::miter_join);
+ stroke.miter_limit(2.0*lineStroke.miterLimit); // miter limit is relative to the half-width
+ break;
+ case SE_LineJoin_Round:
+ default:
+ stroke.line_join(agg::round_join);
+ break;
+ }
+
+ c->rasterizer.add_path(stroke);
+ c->rasterizer.filling_rule(agg::fill_non_zero);
+
+ c->renderer_scanline.color(utfpix32(lineStroke.color));
+ agg::render_scanlines(c->rasterizer, c->scanline_utf, c->renderer_scanline);
+
+ c->rasterizer.filling_rule(agg::fill_even_odd);
+}
+
+void UTFGridRenderer::DrawScreenPolygon(LineBuffer * polygon, const SE_Matrix * xform, unsigned int /*fill*/)
+{
+ // if you have no geoms, why do you call us at all?
+ if (polygon->geom_count() == 0)
+ return;
+
+ // transform to screen coords and transfer to AGG storage
+ unsigned int* pathids = (unsigned int*)alloca(polygon->geom_count() * sizeof(unsigned int));
+ _TransferPoints(m_context, polygon, xform, pathids);
+
+ for (int i = 0; i<polygon->geom_count(); ++i)
+ {
+ m_context->rasterizer.reset();
+ m_context->rasterizer.add_path(m_context->ps, pathids[i]);
+
+ m_context->renderer_scanline.color(utfpix32(m_currentColor));
+ agg::render_scanlines(m_context->rasterizer, m_context->scanline_utf, m_context->renderer_scanline);
+ }
+}
+
+void UTFGridRenderer::DrawScreenRaster(unsigned char * /*data*/, int /*length*/, RS_ImageFormat /*format*/, int /*native_width*/, int /*native_height*/, double /*x*/, double /*y*/, double /*w*/, double /*h*/, double /*angleDeg*/)
+{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::DrawScreenRaster(unsigned char * data, int length, RS_ImageFormat format, int native_width, int native_height, double x, double y, double w, double h, double angleDeg, double alpha)
+void UTFGridRenderer::DrawScreenRaster(unsigned char * /*data*/, int /*length*/, RS_ImageFormat /*format*/, int /*native_width*/, int /*native_height*/, double /*x*/, double /*y*/, double /*w*/, double /*h*/, double /*angleDeg*/, double /*alpha*/)
{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::DrawScreenText(const RS_TextMetrics & tm, RS_TextDef & tdef, double insx, double insy, RS_F_Point * path, int npts, double param_position)
+void UTFGridRenderer::DrawScreenText(const RS_TextMetrics & /*tm*/, RS_TextDef & /*tdef*/, double /*insx*/, double /*insy*/, RS_F_Point * /*path*/, int /*npts*/, double /*param_position*/)
{
//Not applicable for UTFGrid
}
@@ -231,12 +532,12 @@
return NULL;
}
-void UTFGridRenderer::ProcessSELabelGroup(SE_LabelInfo * labels, int nlabels, RS_OverpostType type, bool exclude, LineBuffer * path)
+void UTFGridRenderer::ProcessSELabelGroup(SE_LabelInfo * /*labels*/, int /*nlabels*/, RS_OverpostType /*type*/, bool /*exclude*/, LineBuffer * /*path*/)
{
//Not applicable for UTFGrid
}
-void UTFGridRenderer::AddExclusionRegion(RS_F_Point * fpts, int npts)
+void UTFGridRenderer::AddExclusionRegion(RS_F_Point * /*fpts*/, int /*npts*/)
{
//Not applicable for UTFGrid
}
Modified: sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h 2017-04-27 12:44:20 UTC (rev 9181)
+++ sandbox/jng/utfgrid/Common/Renderers/UTFGridRenderer.h 2017-05-01 15:51:03 UTC (rev 9182)
@@ -20,11 +20,17 @@
#include "Renderers.h"
#include "SE_Renderer.h"
+#include "UTFGridContent.h"
+#define UTF_GRID_WIDTH 256
+#define UTF_GRID_HEIGHT 256
+
+class agg_utfgrid_context;
+
class UTFGridRenderer : public SE_Renderer
{
public:
- RENDERERS_API UTFGridRenderer();
+ RENDERERS_API UTFGridRenderer(UTFGridContent* utfGrid);
RENDERERS_API virtual ~UTFGridRenderer();
// Inherited via SE_Renderer
@@ -67,7 +73,14 @@
RENDERERS_API virtual void ProcessSELabelGroup(SE_LabelInfo * labels, int nlabels, RS_OverpostType type, bool exclude, LineBuffer * path = NULL);
RENDERERS_API virtual void AddExclusionRegion(RS_F_Point * fpts, int npts);
+ RENDERERS_API static void DrawScreenPolyline(agg_utfgrid_context* cxt, LineBuffer* polyline, const SE_Matrix* xform, const SE_LineStroke& lineStroke);
+
private:
+
+ void ProcessOneMarker(double x, double y, RS_MarkerDef& mdef, bool allowOverpost);
+ double _MeterToMapSize(RS_Units unit, double number);
+ static void _TransferPoints(agg_utfgrid_context* c, LineBuffer* src, const SE_Matrix* xform, unsigned int* pathids);
+
RS_Bounds m_extents;
double m_drawingScale;
double m_metersPerUnit;
@@ -79,13 +92,20 @@
RS_LayerUIInfo* m_layerInfo;
RS_FeatureClassInfo* m_fcInfo;
- RS_FeatureReader* m_currentFeature;
+ unsigned int m_currentColor;
SE_Matrix m_xform;
SE_Matrix m_ixform;
+ agg_utfgrid_context* m_context;
+
+ //screen buffer
+ unsigned int* m_rows;
+
//Not used, just passed around to satisfy required func signatures
SE_LineStroke m_lineStroke;
+
+ UTFGridContent* m_content;
};
#endif
\ No newline at end of file
Added: sandbox/jng/utfgrid/Common/Renderers/agg_utfgrid_context.h
===================================================================
--- sandbox/jng/utfgrid/Common/Renderers/agg_utfgrid_context.h (rev 0)
+++ sandbox/jng/utfgrid/Common/Renderers/agg_utfgrid_context.h 2017-05-01 15:51:03 UTC (rev 9182)
@@ -0,0 +1,109 @@
+//
+// Copyright (C) 2007-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+
+#ifndef _AGGUTFGRIDCONTEXT_H_
+#define _AGGUTFGRIDCONTEXT_H_
+
+#include <map>
+#include "agg_basics.h"
+#include "agg_rendering_buffer.h"
+#include "agg_scanline_u.h"
+#include "agg_scanline_bin.h"
+#include "agg_renderer_scanline.h"
+#include "agg_renderer_outline_aa.h"
+#include "agg_renderer_outline_image.h"
+#include "agg_renderer_primitives.h"
+#include "agg_rasterizer_scanline_aa.h"
+#include "agg_rasterizer_outline_aa.h"
+#include "agg_rasterizer_outline.h"
+#include "agg_conv_curve.h"
+#include "agg_conv_contour.h"
+#include "agg_pixfmt_rgba.h"
+#include "agg_path_storage.h"
+#include "agg_conv_stroke.h"
+#include "agg_font_freetype.h"
+#include "agg_span_interpolator_linear.h"
+#include "agg_image_accessors.h"
+#include "agg_span_pattern_rgba.h"
+#include "agg_trans_affine.h"
+#include "agg_conv_transform.h"
+#include "agg_span_image_filter_rgba.h"
+#include "agg_span_image_filter_rgb.h"
+#include "agg_span_allocator.h"
+#include "agg_pattern_filters_rgba.h"
+#include "agg_font_freetype.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_pixfmt_amask_adaptor.h"
+#include "agg_alpha_mask_u8.h"
+
+#include "MapUTFGrid.h"
+
+typedef agg::int32u utfgrid_band_type;
+typedef agg::row_ptr_cache<utfgrid_band_type> utfgrid_rendering_buffer;
+typedef pixfmt_utf<utfpix32, utfgrid_rendering_buffer> pixfmt_utf32;
+typedef agg::renderer_base<pixfmt_utf32> utfgrid_renderer_base;
+typedef agg::rasterizer_scanline_aa<> utfgrid_rasterizer_scanline;
+typedef agg::renderer_scanline_bin_solid<utfgrid_renderer_base> utfgrid_renderer_scanline;
+
+static utfpix32 UTF_WATER = utfpix32(32);
+
+// encapsulates our rendering context
+class agg_utfgrid_context
+{
+public:
+ agg_utfgrid_context(utfgrid_band_type* rows, int width, int height)
+ {
+ if (!rows)
+ {
+ ownrows = true;
+ m_rows = new utfgrid_band_type[width*height];
+ }
+ else
+ {
+ ownrows = false;
+ m_rows = rows;
+ }
+
+ int stride = width * sizeof(utfgrid_band_type);
+ rendering_buffer.attach(m_rows, width, height, stride);
+ pixel_format.attach(rendering_buffer);
+ renderer_base.attach(pixel_format);
+ renderer_scanline.attach(renderer_base);
+ renderer_base.clear(UTF_WATER);
+ rasterizer.gamma(agg::gamma_none());
+ }
+
+ ~agg_utfgrid_context()
+ {
+ if (ownrows)
+ delete[] m_rows;
+ }
+
+ // rendering buffer
+ unsigned int* m_rows;
+ bool ownrows;
+ utfgrid_rendering_buffer rendering_buffer;
+ pixfmt_utf32 pixel_format;
+ agg::path_storage ps;
+ utfgrid_renderer_base renderer_base;
+ agg::scanline_bin scanline_utf;
+ utfgrid_rasterizer_scanline rasterizer;
+ utfgrid_renderer_scanline renderer_scanline;
+};
+
+#endif
\ No newline at end of file
More information about the mapguide-commits
mailing list