[mapserver-commits] r9104 - sandbox/davidK

svn at osgeo.org svn at osgeo.org
Sun Jun 14 14:28:42 EDT 2009


Author: davidK
Date: 2009-06-14 14:28:42 -0400 (Sun, 14 Jun 2009)
New Revision: 9104

Modified:
   sandbox/davidK/mapkmlrenderer.cpp
   sandbox/davidK/mapkmlrenderer.h
Log:
added lines and polygon symbology
added geometry attributes altitudeMode, extrude, tessellate
added mapfile projection test

Modified: sandbox/davidK/mapkmlrenderer.cpp
===================================================================
--- sandbox/davidK/mapkmlrenderer.cpp	2009-06-11 19:46:16 UTC (rev 9103)
+++ sandbox/davidK/mapkmlrenderer.cpp	2009-06-14 18:28:42 UTC (rev 9104)
@@ -5,8 +5,11 @@
 #include "mapkmlrenderer.h"
 #include "mapio.h"
 
+#define	LAYER_FOLDER_STYLE		"LayerFolder"
+#define	LAYER_FOLDER_STYLE_URL	"#LayerFolder"
+
 KmlRenderer::KmlRenderer(int width, int height, colorObj* color/*=NULL*/) 
-	:	XmlDoc(NULL), LayerNode(NULL)
+	:	XmlDoc(NULL), LayerNode(NULL), FirstLayer(true)
 {
 	//	Create document.
     XmlDoc = xmlNewDoc(BAD_CAST "1.0");
@@ -20,6 +23,11 @@
 
 	DocNode = xmlNewChild(rootNode, NULL, BAD_CAST "Document", NULL);
 
+	xmlNodePtr styleNode = xmlNewChild(DocNode, NULL, BAD_CAST "Style", NULL);
+	xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST LAYER_FOLDER_STYLE);
+	xmlNodePtr listStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "ListStyle", NULL);
+	xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", BAD_CAST "checkHideChildren");
+
 	StyleHashTable = msCreateHashTable();
 }
 
@@ -83,20 +91,86 @@
 {
 }
 
+void KmlRenderer::setupRenderingParams(hashTableObj *layerMetadata)
+{
+	AltitudeMode = 0;
+	Extrude = 0;
+	Tessellate = 0;
+
+	char *altitudeModeVal = msLookupHashTable(layerMetadata, "kml_altitudeMode");
+	if (altitudeModeVal)
+	{
+		if(strcasecmp(altitudeModeVal, "absolute") == 0)
+			AltitudeMode = absolute;
+		else if(strcasecmp(altitudeModeVal, "relativeToGround") == 0)
+			AltitudeMode = relativeToGround;
+		else if(strcasecmp(altitudeModeVal, "clampToGround") == 0)
+			AltitudeMode = clampToGround;
+	}
+
+	char *extrudeVal = msLookupHashTable(layerMetadata, "kml_extrude");
+	if (altitudeModeVal)
+	{
+		Extrude = atoi(extrudeVal);
+	}
+
+	char *tessellateVal = msLookupHashTable(layerMetadata, "kml_tessellate");
+	if (tessellateVal)
+	{
+		Tessellate = atoi(tessellateVal);
+	}
+}
+
+int KmlRenderer::checkProjection(projectionObj *projection)
+{
+#ifdef USE_PROJ
+	if (projection && projection->numargs > 0 && pj_is_latlong(projection->proj))
+	{
+		char *projStr = msGetProjectionString(projection);
+
+		/* is ellipsoid WGS84 or projection code epsg:4326 */
+		if (strcasestr(projStr, "WGS84") || strcasestr(projStr,"epsg:4326"))
+		{
+			return MS_SUCCESS;
+		}
+	}
+
+	msSetError(MS_PROJERR, "Mapfile projection not defined, KML output driver requires projection WGS84 (epsg:4326)", "KmlRenderer::checkProjection()" );
+	return MS_FAILURE;
+
+#else
+	msSetError(MS_MISCERR, "Projection support not enabled", "KmlRenderer::checkProjection" );
+	return MS_FAILURE;
+#endif
+}
+
 void KmlRenderer::startNewLayer(imageObj *img, layerObj *layer)
 {
 	LayerNode = xmlNewChild(DocNode, NULL, BAD_CAST "Folder", NULL);
 	
-	xmlNodePtr layerNameNode = xmlNewChild(LayerNode, NULL, BAD_CAST "name", NULL);
-	xmlNodeAddContent(layerNameNode, BAD_CAST layer->name);
+	xmlNewChild(LayerNode, NULL, BAD_CAST "name", BAD_CAST layer->name);
 
-	xmlNodePtr layerVisibilityNode = xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", NULL);
-	xmlNodeAddContent(layerVisibilityNode, BAD_CAST "1");
+	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)
+	{
+		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);
+		FirstLayer = false;
+	}
 }
 
 void KmlRenderer::closeNewLayer(imageObj *img, layerObj *layer)
 {
-	
+
 }
 
 xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl)
@@ -113,12 +187,11 @@
 {
 	xmlNodePtr placemarkNode = createPlacemarkNode(LayerNode, lookupLineStyle(style));
 
-	int includeZ = 0;
-
 	if (p->numlines == 1)
 	{
 		xmlNodePtr geomNode = xmlNewChild(placemarkNode, NULL, BAD_CAST "LineString", NULL);
-		addCoordsNode(geomNode, p->line[0].point, p->line[0].numpoints, includeZ);
+		addAddRenderingSpecifications(geomNode);
+		addCoordsNode(geomNode, p->line[0].point, p->line[0].numpoints);
 	}
 	else
 	{
@@ -126,7 +199,8 @@
 		for (int i=0; i<p->numlines; i++)
 		{
 			xmlNodePtr lineStringNode = xmlNewChild(multiGeomNode, NULL, BAD_CAST "LineString", NULL);
-			addCoordsNode(lineStringNode, p->line[i].point, p->line[i].numpoints, includeZ);
+			addAddRenderingSpecifications(lineStringNode);
+			addCoordsNode(lineStringNode, p->line[i].point, p->line[i].numpoints);
 		}
 	}
 }
@@ -136,8 +210,6 @@
 	xmlNodePtr placemarkNode = createPlacemarkNode(LayerNode, lookupPolyStyle(color));
 	xmlNodePtr polygonNode = xmlNewChild(placemarkNode, NULL, BAD_CAST "Polygon", NULL);
 
-	int includeZ = 0;
-
 	for (int i=0; i<p->numlines; i++)
 	{
 		xmlNodePtr bdryNode = NULL;
@@ -148,11 +220,12 @@
 			bdryNode = xmlNewChild(polygonNode, NULL, BAD_CAST "innerBoundaryIs", NULL);
 
 		xmlNodePtr ringNode = xmlNewChild(bdryNode, NULL, BAD_CAST "LinearRing", NULL);
-		addCoordsNode(ringNode, p->line[i].point, p->line[i].numpoints, includeZ);
+		addAddRenderingSpecifications(ringNode);
+		addCoordsNode(ringNode, p->line[i].point, p->line[i].numpoints);
 	}
 }
 
-void KmlRenderer::addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts, int includeZ)
+void KmlRenderer::addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts)
 {
 	char lineBuf[128];
 
@@ -161,12 +234,12 @@
 
 	for (int i=0; i<numPts; i++)
 	{
-		if (includeZ)
+		if (AltitudeMode == relativeToGround || AltitudeMode == absolute)
 		{
 #ifdef USE_POINT_Z_M
 			sprintf(lineBuf, "\t%.8f,%.8f,%.8f\n", pts[i].x, pts[i].y, pts[i].z);
 #else
-			msSetError(MS_QUERYERR, "Z coordinates support not available  (mapserver not compiled with USE_POINT_Z_M option)", "KmlRenderer::addCoordsNode");
+			msSetError(MS_MISCERR, "Z coordinates support not available  (mapserver not compiled with USE_POINT_Z_M option)", "KmlRenderer::addCoordsNode()");
 #endif
 		}
 		else
@@ -272,22 +345,45 @@
 	xmlNewChild(placemarkNode, NULL, BAD_CAST "name", BAD_CAST text);
 	xmlNodePtr pointNode = xmlNewChild(placemarkNode, NULL, BAD_CAST "Point", NULL);
 
-	int includeZ = false;
+	addAddRenderingSpecifications(pointNode);
 
 	pointObj pt;
 	pt.x = x; pt.y = y;
-	addCoordsNode(pointNode, &pt, 1, includeZ);
+	addCoordsNode(pointNode, &pt, 1);
 }
 
 int KmlRenderer::getTruetypeTextBBox(imageObj *img,char *font, double size, char *string,
 		rectObj *rect, double **advances)
 {
-    rect->minx=0.0;
-    rect->maxx=0.0;
-    rect->miny=0.0;
+    rect->minx=0.0;
+    rect->maxx=0.0;
+    rect->miny=0.0;
     rect->maxy=0.0;
 
 	return true;
 }
 
+void KmlRenderer::addAddRenderingSpecifications(xmlNodePtr node)
+{
+	/*
+	<extrude>0</extrude>                   <!-- boolean -->
+	<tessellate>0</tessellate>             <!-- boolean -->
+	<altitudeMode>clampToGround</altitudeMode> 
+	*/
+
+	if (Extrude)
+		xmlNewChild(node, NULL, BAD_CAST "extrude", BAD_CAST "1");
+
+	if (Tessellate)
+		xmlNewChild(node, NULL, BAD_CAST "tessellate", BAD_CAST "1");
+
+	if (AltitudeMode == absolute)
+		xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "absolute");
+	else if (AltitudeMode == relativeToGround)
+		xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "relativeToGround");
+	else if (AltitudeMode == clampToGround)
+		xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "clampToGround");
+}
+
+
 #endif
\ No newline at end of file

Modified: sandbox/davidK/mapkmlrenderer.h
===================================================================
--- sandbox/davidK/mapkmlrenderer.h	2009-06-11 19:46:16 UTC (rev 9103)
+++ sandbox/davidK/mapkmlrenderer.h	2009-06-14 18:28:42 UTC (rev 9104)
@@ -17,6 +17,14 @@
 
 	hashTableObj *StyleHashTable;
 
+	int			AltitudeMode;
+	int			Tessellate;
+	int			Extrude;
+
+	int			FirstLayer;
+
+	enum altitudeModeEnum { undefined, clampToGround, relativeToGround, absolute };
+
 protected:
 
 	xmlNodePtr createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl);
@@ -25,8 +33,13 @@
 	char* lookupLineStyle(strokeStyleObj *strokeStyle);
 	char* lookupPolyStyle(colorObj *color);
 
-	void addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts, int includeZ);
+	void addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts);
 
+	void setupRenderingParams(hashTableObj *layerMetadata);
+	void addAddRenderingSpecifications(xmlNodePtr node);
+
+	int checkProjection(projectionObj *projection);
+
 public:
 
 	KmlRenderer(int width, int height, colorObj* color = NULL);



More information about the mapserver-commits mailing list