[mapserver-commits] r9242 - sandbox/davidK
svn at osgeo.org
svn at osgeo.org
Thu Aug 6 18:20:43 EDT 2009
Author: davidK
Date: 2009-08-06 18:20:42 -0400 (Thu, 06 Aug 2009)
New Revision: 9242
Added:
sandbox/davidK/Bin/
Modified:
sandbox/davidK/mapdraw.c
sandbox/davidK/mapkml.cpp
sandbox/davidK/mapkmlrenderer.cpp
sandbox/davidK/mapkmlrenderer.h
Log:
added support for selecting vector/raster kml output based on features count
Modified: sandbox/davidK/mapdraw.c
===================================================================
--- sandbox/davidK/mapdraw.c 2009-08-03 14:23:34 UTC (rev 9241)
+++ sandbox/davidK/mapdraw.c 2009-08-06 22:20:42 UTC (rev 9242)
@@ -825,19 +825,25 @@
/* deref and possibly free temporary transparent output format. */
msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE, MS_NOOVERRIDE, MS_NOOVERRIDE );
}
- else if( MS_RENDERER_PLUGIN(image_draw->format) && layer->opacity > 0 && layer->opacity < 100 ) {
- rendererVTableObj *renderer = image_draw->format->vtable;
- if (!renderer->supports_transparent_layers) {
- rasterBufferObj rb;
- renderer->getRasterBuffer(image_draw,&rb);
- renderer->mergeRasterBuffer(image,&rb,layer->opacity*0.01,0,0);
- renderer->freeImage( image_draw );
-
- /* deref and possibly free temporary transparent output format. */
- msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE, MS_NOOVERRIDE, MS_NOOVERRIDE );
- } else {
- renderer->closeNewLayer(image_draw,layer);
+ else if( MS_RENDERER_PLUGIN(image_draw->format))
+ {
+
+ if (layer->opacity > 0 && layer->opacity < 100 )
+ {
+ rendererVTableObj *renderer = image_draw->format->vtable;
+ if (!renderer->supports_transparent_layers)
+ {
+ rasterBufferObj rb;
+ renderer->getRasterBuffer(image_draw,&rb);
+ renderer->mergeRasterBuffer(image,&rb,layer->opacity*0.01,0,0);
+ renderer->freeImage( image_draw );
+
+ /* deref and possibly free temporary transparent output format. */
+ msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE, MS_NOOVERRIDE, MS_NOOVERRIDE );
+ }
}
+
+ image_draw->format->vtable->closeNewLayer(image_draw, layer);
}
#ifdef USE_AGG
else if( MS_RENDERER_AGG(image_draw->format) && layer->opacity > 0 && layer->opacity < 100 ) {
Modified: sandbox/davidK/mapkml.cpp
===================================================================
--- sandbox/davidK/mapkml.cpp 2009-08-03 14:23:34 UTC (rev 9241)
+++ sandbox/davidK/mapkml.cpp 2009-08-06 22:20:42 UTC (rev 9242)
@@ -1,3 +1,32 @@
+/******************************************************************************
+ *
+ *
+ * Project: MapServer
+ * Purpose: Headers for mapkml.cpp Google Earth KML output
+ * Author: David Kana and the MapServer team
+ *
+ ******************************************************************************
+ * Copyright (c) 1996-2009 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.
+ *****************************************************************************/
+
#include "mapserver.h"
#include "mapkmlrenderer.h"
Modified: sandbox/davidK/mapkmlrenderer.cpp
===================================================================
--- sandbox/davidK/mapkmlrenderer.cpp 2009-08-03 14:23:34 UTC (rev 9241)
+++ sandbox/davidK/mapkmlrenderer.cpp 2009-08-06 22:20:42 UTC (rev 9242)
@@ -1,3 +1,32 @@
+/******************************************************************************
+ *
+ *
+ * Project: MapServer
+ * Purpose: Google Earth KML output
+ * Author: David Kana and the MapServer team
+ *
+ ******************************************************************************
+ * Copyright (c) 1996-2009 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.
+ *****************************************************************************/
+
#ifdef USE_KML
#include "mapserver.h"
@@ -9,7 +38,7 @@
#define LAYER_FOLDER_STYLE_URL "#LayerFolder"
KmlRenderer::KmlRenderer(int width, int height, colorObj* color/*=NULL*/)
- : XmlDoc(NULL), LayerNode(NULL), Width(width), Height(height),
+ : XmlDoc(NULL), LayerNode(NULL), GroundOverlayNode(NULL), Width(width), Height(height),
FirstLayer(true), RasterizerOutputFormat(NULL), InternalImg(NULL),
VectorMode(true), RasterMode(false), MapCellsize(1.0),
PlacemarkNode(NULL), GeomNode(NULL)
@@ -64,7 +93,7 @@
int KmlRenderer::saveImage(imageObj *img, FILE *fp, outputFormatObj *format)
{
//
- if (false && InternalImg)
+ if (InternalImg)
{
char fileName[512];
@@ -89,6 +118,12 @@
createGroundOverlayNode(fileName);
}
+ else
+ {
+ xmlUnlinkNode(GroundOverlayNode);
+ xmlFreeNode(GroundOverlayNode);
+ GroundOverlayNode = NULL;
+ }
/* -------------------------------------------------------------------- */
/* Write out the document. */
@@ -132,6 +167,108 @@
{
}
+void KmlRenderer::startNewLayer(imageObj *img, layerObj *layer)
+{
+ //LayerNode = xmlNewChild(DocNode, NULL, BAD_CAST "Folder", NULL);
+
+ LayerNode = xmlNewNode(NULL, BAD_CAST "Folder");
+
+ xmlNewChild(LayerNode, NULL, BAD_CAST "name", BAD_CAST layer->name);
+
+ char *layerVisibility = layer->status != MS_OFF ? "1" : "0";
+ xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", BAD_CAST layerVisibility);
+
+ xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST LAYER_FOLDER_STYLE_URL);
+
+ VectorMode = true;
+ RasterMode = true;
+
+ setupRenderingParams(&layer->metadata);
+
+ if (FirstLayer)
+ {
+ FirstLayer = false;
+
+ // map rect for ground overlay
+ MapExtent = layer->map->extent;
+ MapCellsize = layer->map->cellsize;
+ BgColor = layer->map->imagecolor;
+
+ if (layer->map->name)
+ xmlNewChild(DocNode, NULL, BAD_CAST "name", BAD_CAST layer->map->name);
+
+ // First rendered layer - check mapfile projection
+ checkProjection(&layer->map->projection);
+
+ // setup internal rasterizer format
+ // default rasterizer cairopng
+ // optional tag formatoption "kml_rasteroutputformat"
+ char rasterizerFomatName[128];
+ sprintf(rasterizerFomatName, "cairopng");
+
+ for (int i=0; i<layer->map->numoutputformats; i++)
+ {
+ const char *formatOptionStr = msGetOutputFormatOption(layer->map->outputformatlist[i],"kml_rasteroutputformat", "");
+ if (strlen(formatOptionStr))
+ {
+ sprintf(rasterizerFomatName, "%s", formatOptionStr);
+ break;
+ }
+ }
+
+ for (int i=0; i<layer->map->numoutputformats; i++)
+ {
+ outputFormatObj *iFormat = layer->map->outputformatlist[i];
+ if(!strcasecmp(iFormat->name,rasterizerFomatName))
+ {
+ //RasterizerOutputFormat = msCloneOutputFormat(iFormat);
+ RasterizerOutputFormat = iFormat;
+
+ //InternalImg = createInternalImage();
+ break;
+ }
+ }
+ }
+
+ // reset feature counter
+ FeatureCount = 0;
+
+ TempImg = RasterMode ? createInternalImage() : NULL;
+}
+
+void KmlRenderer::closeNewLayer(imageObj *img, layerObj *layer)
+{
+ flushPlacemark();
+
+ if (FeatureCount > MaxFeatureCount)
+ {
+ // layer was rasterized, merge temp layer image with main output image
+
+ if (!InternalImg)
+ {
+ InternalImg = TempImg;
+ }
+ else
+ {
+ rendererVTableObj *r = RasterizerOutputFormat->vtable;
+
+ rasterBufferObj data;
+ r->getRasterBuffer(TempImg,&data);
+
+ r->mergeRasterBuffer(InternalImg, &data, layer->opacity * 0.01, 0, 0);
+
+ msFreeImage(TempImg);
+ }
+
+ xmlFreeNode(LayerNode);
+ }
+ else
+ {
+ xmlAddChild(DocNode, LayerNode);
+ }
+}
+
+
void KmlRenderer::setupRenderingParams(hashTableObj *layerMetadata)
{
AltitudeMode = 0;
@@ -160,6 +297,24 @@
{
Tessellate = atoi(tessellateVal);
}
+
+ char *maxFeatureVal = msLookupHashTable(layerMetadata, "kml_maxfeaturecount");
+ if (maxFeatureVal)
+ {
+ MaxFeatureCount = atoi(maxFeatureVal);
+ if (MaxFeatureCount >= 999999)
+ RasterMode = false;
+
+ if (MaxFeatureCount == 0)
+ VectorMode = false;
+ }
+ else
+ {
+ // no kml_maxfeaturecount tag found, set default feature count to 128
+ // if FeatureCount is greater than MaxFeatureCount, layer is rasterized and
+ // rendered as ground overlay
+ MaxFeatureCount = 128;
+ }
}
int KmlRenderer::checkProjection(projectionObj *projection)
@@ -185,55 +340,15 @@
#endif
}
-void KmlRenderer::startNewLayer(imageObj *img, layerObj *layer)
+xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl)
{
- LayerNode = xmlNewChild(DocNode, NULL, BAD_CAST "Folder", NULL);
-
- xmlNewChild(LayerNode, NULL, BAD_CAST "name", BAD_CAST layer->name);
-
- char *layerVisibility = layer->status != MS_OFF ? "1" : "0";
- xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", BAD_CAST layerVisibility);
-
- xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST LAYER_FOLDER_STYLE_URL);
-
- setupRenderingParams(&layer->metadata);
-
- if (FirstLayer)
+ FeatureCount++;
+ if (FeatureCount > MaxFeatureCount)
{
- FirstLayer = false;
-
- // map rect for ground overlay
- MapExtent = layer->map->extent;
- MapCellsize = layer->map->cellsize;
- BgColor = layer->map->imagecolor;
-
- if (layer->map->name)
- xmlNewChild(DocNode, NULL, BAD_CAST "name", BAD_CAST layer->map->name);
-
- // First rendered layer - check mapfile projection
- checkProjection(&layer->map->projection);
-
- for (int i=0; i<layer->map->numoutputformats; i++)
- {
- outputFormatObj *iFormat = layer->map->outputformatlist[i];
- if(!strcasecmp(iFormat->driver,"cairo/png"))
- {
- //RasterizerOutputFormat = msCloneOutputFormat(iFormat);
- RasterizerOutputFormat = iFormat;
- InternalImg = createInternalImage();
- break;
- }
- }
+ VectorMode = false;
+ return NULL;
}
-}
-void KmlRenderer::closeNewLayer(imageObj *img, layerObj *layer)
-{
- flushPlacemark();
-}
-
-xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl)
-{
xmlNodePtr placemarkNode = xmlNewChild(parentNode, NULL, BAD_CAST "Placemark", NULL);
if (styleUrl)
@@ -250,6 +365,9 @@
if (PlacemarkNode == NULL)
PlacemarkNode = createPlacemarkNode(LayerNode, NULL);
+ if (!PlacemarkNode)
+ return;
+
memcpy(&LineStyle, style, sizeof(strokeStyleObj));
SymbologyFlag[Line] = 1;
@@ -292,7 +410,7 @@
r->transformShape(&rasShape, MapExtent, MapCellsize);
- r->renderLine(InternalImg, &rasShape, style);
+ r->renderLine(TempImg, &rasShape, style);
msFreeShape(&rasShape);
}
}
@@ -302,6 +420,9 @@
if (PlacemarkNode == NULL)
PlacemarkNode = createPlacemarkNode(LayerNode, NULL);
+ if (!PlacemarkNode)
+ return;
+
memcpy(&PolygonColor, color, sizeof(colorObj));
SymbologyFlag[Polygon] = 1;
@@ -344,7 +465,7 @@
r->transformShape(&rasShape, MapExtent, MapCellsize);
- r->renderPolygon(InternalImg, &rasShape, color);
+ r->renderPolygon(TempImg, &rasShape, color);
msFreeShape(&rasShape);
}
}
@@ -379,6 +500,9 @@
if (PlacemarkNode == NULL)
PlacemarkNode = createPlacemarkNode(LayerNode, NULL);
+ if (!PlacemarkNode)
+ return;
+
memcpy(&LabelStyle, style, sizeof(labelStyleObj));
SymbologyFlag[Label] = 1;
@@ -401,7 +525,7 @@
{
// internal renderer used for rasterizing
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->renderGlyphs(InternalImg, x, y, style, text);
+ r->renderGlyphs(TempImg, x, y, style, text);
}
}
@@ -420,7 +544,7 @@
if (RasterMode)
{
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->getTruetypeTextBBox(InternalImg, font, size, string, rect, advances);
+ r->getTruetypeTextBBox(TempImg, font, size, string, rect, advances);
}
return true;
@@ -510,6 +634,9 @@
if (PlacemarkNode == NULL)
PlacemarkNode = createPlacemarkNode(LayerNode, NULL);
+ if (!PlacemarkNode)
+ return;
+
sprintf(SymbolUrl, "%s", lookupSymbolUrl(symbol, style));
SymbologyFlag[Symbol] = 1;
@@ -529,7 +656,7 @@
if (RasterMode)
{
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->renderPixmapSymbol(InternalImg, x, y, symbol, style);
+ r->renderPixmapSymbol(TempImg, x, y, symbol, style);
}
}
@@ -541,7 +668,7 @@
if (RasterMode)
{
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->renderVectorSymbol(InternalImg, x, y, symbol, style);
+ r->renderVectorSymbol(TempImg, x, y, symbol, style);
}
}
@@ -553,7 +680,7 @@
if (RasterMode)
{
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->renderEllipseSymbol(InternalImg, x, y, symbol, style);
+ r->renderEllipseSymbol(TempImg, x, y, symbol, style);
}
}
@@ -565,11 +692,11 @@
if (RasterMode)
{
rendererVTableObj *r = RasterizerOutputFormat->vtable;
- r->renderTruetypeSymbol(InternalImg, x, y, symbol, style);
+ r->renderTruetypeSymbol(TempImg, x, y, symbol, style);
}
}
-void KmlRenderer::createGroundOverlayNode(char *imageHref)
+xmlNodePtr KmlRenderer::createGroundOverlayNode(char *imageHref)
{
/*
<?xml version="1.0" encoding="UTF-8"?>
@@ -597,10 +724,13 @@
xmlNodePtr groundOverlayNode = xmlNewChild(DocNode, NULL, BAD_CAST "GroundOverlay", NULL);
xmlNewChild(groundOverlayNode, NULL, BAD_CAST "color", BAD_CAST "ffffffff");
- xmlNewChild(groundOverlayNode, NULL, BAD_CAST "drawOrder", BAD_CAST "1");
+ xmlNewChild(groundOverlayNode, NULL, BAD_CAST "drawOrder", BAD_CAST "0");
- xmlNodePtr iconNode = xmlNewChild(groundOverlayNode, NULL, BAD_CAST "Icon", NULL);
- xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST imageHref);
+ if (imageHref)
+ {
+ xmlNodePtr iconNode = xmlNewChild(groundOverlayNode, NULL, BAD_CAST "Icon", NULL);
+ xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST imageHref);
+ }
char crdStr[64];
xmlNodePtr latLonBoxNode = xmlNewChild(groundOverlayNode, NULL, BAD_CAST "LatLonBox", NULL);
@@ -617,6 +747,8 @@
xmlNewChild(latLonBoxNode, NULL, BAD_CAST "east", BAD_CAST crdStr);
xmlNewChild(latLonBoxNode, NULL, BAD_CAST "rotation", BAD_CAST "0.0");
+
+ return groundOverlayNode;
}
void KmlRenderer::startShape(imageObj *img, shapeObj *shape)
Modified: sandbox/davidK/mapkmlrenderer.h
===================================================================
--- sandbox/davidK/mapkmlrenderer.h 2009-08-03 14:23:34 UTC (rev 9241)
+++ sandbox/davidK/mapkmlrenderer.h 2009-08-06 22:20:42 UTC (rev 9242)
@@ -1,3 +1,33 @@
+/******************************************************************************
+ *
+ *
+ * Project: MapServer
+ * Purpose: Headers for mapkmlrenderer.cpp Google Earth KML output
+ * Author: David Kana and the MapServer team
+ *
+ ******************************************************************************
+ * Copyright (c) 1996-2009 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 MAPKMLRENDERER_H
#define MAPKMLRENDERER_H
@@ -21,6 +51,7 @@
xmlDocPtr XmlDoc;
xmlNodePtr DocNode;
xmlNodePtr LayerNode;
+ xmlNodePtr GroundOverlayNode;
xmlNodePtr PlacemarkNode;
xmlNodePtr GeomNode;
@@ -46,6 +77,16 @@
outputFormatObj *RasterizerOutputFormat;
imageObj *InternalImg;
+ imageObj *TempImg;
+
+ int FirstLayer;
+
+ // max number of features rendered in "vector KML" mode
+ int MaxFeatureCount;
+
+ // number of features in layer
+ int FeatureCount;
+
// if true - features are rasterized
int VectorMode;
@@ -56,15 +97,13 @@
int Tessellate;
int Extrude;
- int FirstLayer;
-
enum altitudeModeEnum { undefined, clampToGround, relativeToGround, absolute };
protected:
imageObj* createInternalImage();
xmlNodePtr createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl);
- void createGroundOverlayNode(char *imageHref);
+ xmlNodePtr createGroundOverlayNode(char *imageHref);
char* lookupPointStyle(colorObj *color);
char* lookupLineStyle(strokeStyleObj *strokeStyle);
More information about the mapserver-commits
mailing list