[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