[postgis-tickets] [SCM] PostGIS branch master updated. 3.3.0rc2-1173-g39c69beb3

git at osgeo.org git at osgeo.org
Thu Jul 6 19:59:10 PDT 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  39c69beb3143c0e1ce10bec7d61a9d87b985d0fa (commit)
      from  37b3c90b52ae06ca94204ed1cb0e75f675eaa830 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 39c69beb3143c0e1ce10bec7d61a9d87b985d0fa
Author: Regina Obe <lr at pcorp.us>
Date:   Wed Jun 28 13:26:09 2023 -0400

    ST_AsSVG support for curves
    
     - Support circularstring,
       compoundcurve, multicurve,
       curvepolygon, multisurface
       in svg (absolute)
     - Relative work in progress
     - Update cu_out_svg.c moving curve examples from unsupported to
       test mode
     - Update docs to reflect curves now supported
    
     Closes #4913
     Closes https://git.osgeo.org/gitea/postgis/postgis/pulls/130

diff --git a/NEWS b/NEWS
index 547948fde..5caf9df73 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,8 @@ PostGIS 3.4.0dev
   - GH734, Additional metadata on Proj installation in postgis_proj_version (Paul Ramsey)
   - #5177, allow building tools without PostgreSQL server headers (Sandro Santilli)
   - ST_Project signature for geometry, and two-point signature (Paul Ramsey)
+  - #4913, ST_AsSVG support for curve types CircularString, CompoundCurve, MultiCurve,
+           and MultiSurface (Regina Obe)
 
 * Bug Fix *
 
diff --git a/doc/reference_output.xml b/doc/reference_output.xml
index 57e2dadd1..60389bbd1 100644
--- a/doc/reference_output.xml
+++ b/doc/reference_output.xml
@@ -1521,20 +1521,53 @@ FROM mvtgeom;
 			geometries are delimited by commas (","), GeometryCollection
 			geometries are delimited by semicolons (";").</para>
 
+        <para>For working with PostGIS SVG graphics, checkout <ulink url="https://github.com/dr-jts/pg_svg">pg_svg</ulink> library which
+        provides plpgsql functions for working with outputs from ST_AsSVG.</para>
+
+        <para role="enhanced" conformance="3.4.0">Enhanced: Support for curves added</para>
+		<para role="changed" conformance="2.0.0">Changed: 2.0.0 to use default args and support named args</para>
 		<note>
 		  <para role="availability" conformance="1.2.2.">Availability: 1.2.2. Availability: 1.4.0  Changed in PostGIS 1.4.0 to include L command in absolute path to conform to <ulink
 			url="http://www.w3.org/TR/SVG/paths.html#PathDataBNF">http://www.w3.org/TR/SVG/paths.html#PathDataBNF</ulink></para>
 		</note>
-		<para role="changed" conformance="2.0.0">Changed: 2.0.0 to use default args and support named args</para>
+        <para>&curve_support;</para>
 	  </refsection>
 
 	  <refsection>
 		<title>Examples</title>
-		<programlisting>SELECT ST_AsSVG('POLYGON((0 0,0 1,1 1,1 0,0 0))');
+		<programlisting>SELECT ST_AsSVG('POLYGON((0 0,0 1,1 1,1 0,0 0))'::geometry);
 
-		st_assvg
-		--------
-		M 0 0 L 0 -1 1 -1 1 0 Z</programlisting>
+st_assvg
+--------
+M 0 0 L 0 -1 1 -1 1 0 Z</programlisting>
+
+        <para>Circular string</para>
+		<programlisting>SELECT ST_AsSVG( ST_GeomFromText('CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)') );
+
+st_assvg
+--------
+M -2 0 A 2 2 0 0 1 2 0 A 2 2 0 0 1 2 -4</programlisting>
+
+        <para>Multi-curve</para>
+        <programlisting>SELECT ST_AsSVG('MULTICURVE((5 5,3 5,3 3,0 3),
+ CIRCULARSTRING(0 0,2 1,2 2))'::geometry, 0, 0);
+ st_assvg
+------------------------------------------------
+ M 5 -5 L 3 -5 3 -3 0 -3 M 0 0 A 2 2 0 0 0 2 -2
+ </programlisting>
+
+        <para>Multi-surface</para>
+        <programlisting>SELECT ST_AsSVG('MULTISURFACE(
+CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),
+    (-1 0,0 0.5,1 0,0 1,-1 0)),
+((7 8,10 10,6 14,4 11,7 8)))'::geometry, 0, 2);
+
+st_assvg
+---------------------------------------------------------
+M -2 0 A 1 1 0 0 0 0 0 A 1 1 0 0 0 2 0 A 2 2 0 0 0 -2 0 Z
+M -1 0 L 0 -0.5 1 0 0 -1 -1 0 Z
+M 7 -8 L 10 -10 6 -14 4 -11 Z
+ </programlisting>
 	  </refsection>
 	</refentry>
 		<refentry id="ST_AsTWKB">
diff --git a/liblwgeom/cunit/cu_out_svg.c b/liblwgeom/cunit/cu_out_svg.c
index 0d15dca43..2c2a945f3 100644
--- a/liblwgeom/cunit/cu_out_svg.c
+++ b/liblwgeom/cunit/cu_out_svg.c
@@ -189,41 +189,49 @@ static void out_svg_test_geoms(void)
 	    "cx=\"0\" cy=\"-1\";M 2 -3 L 4 -5",
 	    0, 0);
 
-	/* Empty GeometryCollection */
-	do_svg_test(
-	    "GEOMETRYCOLLECTION EMPTY",
-	    "",
-	    0, 0);
-
-	/* Nested GeometryCollection */
-	do_svg_unsupported(
-	    "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
-	    "assvg_geom_buf: 'GeometryCollection' geometry type not supported.");
-
 	/* CircularString */
-	do_svg_unsupported(
+	do_svg_test(
 	    "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
-	    "lwgeom_to_svg: 'CircularString' geometry type not supported");
+	    "M -2 0 A 2 2 0 0 1 2 0 A 2 2 0 0 1 2 -4",
+			0, 0);
+
+	/* : Circle */
+	do_svg_test(
+	    "CIRCULARSTRING(4 2,-2 2,4 2)",
+	    "M 1 -2 m 3 0 a 3 3 0 1 0 -6 0 a 3 3 0 1 0 6 0",
+			0, 0);
 
 	/* CompoundCurve */
-	do_svg_unsupported(
+	do_svg_test(
 	    "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))",
-	    "lwgeom_to_svg: 'CompoundCurve' geometry type not supported");
-
-	/* CurvePolygon */
-	do_svg_unsupported(
-	    "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
-	    "lwgeom_to_svg: 'CurvePolygon' geometry type not supported");
+	    "M 0 0 A 1 1 0 1 1 1 0 L 0 -1", 0, 0);
 
 	/* MultiCurve */
-	do_svg_unsupported(
+	do_svg_test(
 	    "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))",
-	    "lwgeom_to_svg: 'MultiCurve' geometry type not supported");
+	    "M 5 -5 L 3 -5 3 -3 0 -3 M 0 0 A 2 2 0 0 0 2 -2", 0, 0);
+
+	/* CurvePolygon */
+	do_svg_test(
+	    "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
+	    "M -2 0 A 1 1 0 0 0 0 0 A 1 1 0 0 0 2 0 A 2 2 0 0 0 -2 0 Z M -1 0 L 0 0 1 0 0 -1 -1 0 Z", 0, 0);
 
 	/* MultiSurface */
-	do_svg_unsupported(
+	do_svg_test(
 	    "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
-	    "lwgeom_to_svg: 'MultiSurface' geometry type not supported");
+	    "M -2 0 A 1 1 0 0 0 0 0 A 1 1 0 0 0 2 0 A 2 2 0 0 0 -2 0 Z M -1 0 L 0 0 1 0 0 -1 -1 0 Z M 7 -8 L 10 -10 6 -14 4 -11 Z", 0, 0);
+
+	/* Empty GeometryCollection */
+	do_svg_test(
+	    "GEOMETRYCOLLECTION EMPTY",
+	    "",
+	    0, 0);
+
+	/* Nested GeometryCollection */
+	do_svg_unsupported(
+	    "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+	    "assvg_geom_buf: 'GeometryCollection' geometry type not supported.");
+
 }
 
 static void out_svg_test_relative(void)
diff --git a/liblwgeom/lwout_svg.c b/liblwgeom/lwout_svg.c
index fc96c1634..c05efc355 100644
--- a/liblwgeom/lwout_svg.c
+++ b/liblwgeom/lwout_svg.c
@@ -41,7 +41,7 @@ assvg_geom(stringbuffer_t* sb, const LWGEOM *geom, int relative, int precision);
 
 
 static void
-pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision)
+pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
 {
 	int i, end;
 	const POINT2D *pt;
@@ -60,7 +60,7 @@ pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int
 	end = close_ring ? pa->npoints : pa->npoints - 1;
 
 	/* Starting point */
-	pt = getPoint2d_cp(pa, 0);
+	pt = getPoint2d_cp(pa, start_at_index);
 
 	x = round(pt->x*f)/f;
 	y = round(pt->y*f)/f;
@@ -75,7 +75,7 @@ pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int
 	accum_y = y;
 
 	/* All the following ones */
-	for (i = 1; i < end; i++)
+	for (i = (start_at_index + 1); i < end; i++)
 	{
 		pt = getPoint2d_cp(pa, i);
 
@@ -99,7 +99,7 @@ pointArray_svg_rel(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int
  * Returns maximum size of rendered pointarray in bytes.
  */
 static void
-pointArray_svg_abs(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision)
+pointArray_svg_abs(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int precision, int start_at_index)
 {
 	int i, end;
 	const POINT2D* pt;
@@ -108,11 +108,19 @@ pointArray_svg_abs(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int
 
 	end = close_ring ? pa->npoints : pa->npoints - 1;
 
-	for (i = 0; i < end; i++)
+	for (i = start_at_index; i < end; i++)
 	{
 		pt = getPoint2d_cp(pa, i);
 
-		if (i == 1) stringbuffer_append(sb, " L ");
+		if (i == 1)
+		{
+			if (start_at_index > 0 ){
+					stringbuffer_append(sb, "L ");
+			}
+			else {
+					stringbuffer_append(sb, " L ");
+			}
+		}
 		else if (i) stringbuffer_append(sb, " ");
 
 		lwprint_double(pt->x, precision, sx);
@@ -146,11 +154,156 @@ assvg_line(stringbuffer_t* sb, const LWLINE *line, int relative, int precision)
 	/* Start path with SVG MoveTo */
 	stringbuffer_append(sb, "M ");
 	if (relative)
-		pointArray_svg_rel(sb, line->points, 1, precision);
+		pointArray_svg_rel(sb, line->points, 1, precision, 0);
 	else
-		pointArray_svg_abs(sb, line->points, 1, precision);
+		pointArray_svg_abs(sb, line->points, 1, precision, 0);
+}
+
+static void pointArray_svg_arc(stringbuffer_t* sb, const POINTARRAY *pa, int close_ring, int relative,  int precision)
+{
+	uint32_t i; //, end;
+	char sx[OUT_DOUBLE_BUFFER_SIZE];
+	char sy[OUT_DOUBLE_BUFFER_SIZE];
+
+	LWDEBUG(2, "pointArray_svg_arc called.");
+
+	for (i = 2; i < pa->npoints; i+=2)
+	{
+		LWDEBUGF(3, "assvg_circstring: arc ending at point %d", i);
+		int largeArcFlag, sweepFlag, clockwise;
+		int is_circle = LW_FALSE;
+		double a1, a3;/**angles**/
+		double radius; /* Arc radius */
+		double total_angle;
+		POINT2D center;
+		const POINT2D *t1;
+		const POINT2D *t2;
+		const POINT2D *t3;
+		int p2_side = 0;
+		t1 = getPoint2d_cp(pa, i - 2);
+		t2 = getPoint2d_cp(pa, i - 1);
+		t3 = getPoint2d_cp(pa, i);
+		radius = lw_arc_center(t1, t2, t3, &center);
+		if ( t1->x == t3->x && t1->y == t3->y ){
+			is_circle = LW_TRUE;
+		}
+		p2_side = lw_segment_side(t1, t3, t2);
+		if ( p2_side == -1 )
+			clockwise = LW_TRUE;
+		else
+			clockwise = LW_FALSE;
+		/* Angles of each point that defines the arc section */
+		a1 = atan2(t1->y - center.y, t1->x - center.x)*180/M_PI;
+		//a2 = atan2(t2->y - center.y, t2->x - center.x)*180/M_PI;
+		a3 = atan2(t3->y - center.y, t3->x - center.x)*180/M_PI;
+
+		LWDEBUGF(2, " center is POINT(%.15g %.15g) - radius:%g", center.x, center.y, radius);
+
+		total_angle = clockwise ? a1 - a3 : a3 - a1;
+		if (total_angle < 0 ){
+			total_angle += 360;
+		}
+
+		//stringbuffer_aprintf(sb, "angles (a1 a2 a3): %g %g %g is_circle: %d, total_angle: %g, t1.x: %f, t3.x: %f, t1.y: %f, t3.y: %f ", a1, a2, a3, is_circle, total_angle, t1->x, t3->x, t1->y, t3->y);
+
+		/** endAngle - startAngle <= 180 ? "0" : "1" **/
+		largeArcFlag = (total_angle <= 180)? 0 : 1;
+		/* The side of the t1/t3 line that t2 falls on dictates the sweep
+		direction from t1 to t3. */
+		sweepFlag = (p2_side == -1) ? 1 : 0;
+		if ( (i == 2) && !is_circle ){
+			/** add MoveTo first point **/
+			lwprint_double(t1->x, precision, sx);
+			lwprint_double(-(t1->y), precision, sy);
+			stringbuffer_aprintf(sb, "%s %s", sx, sy);
+		}
+		/** is circle: need to start at center of circle **/
+		if ( (i == 2) && is_circle){
+			/** add MoveTo center of circle **/
+			lwprint_double(center.x, precision, sx);
+			lwprint_double(-(center.y), precision, sy);
+			stringbuffer_aprintf(sb, "%s %s", sx, sy);
+		}
+		lwprint_double(radius, precision, sx);
+		lwprint_double(0, precision, sy);
+		/** is circle need to handle differently **/
+		if (is_circle){
+			//https://stackoverflow.com/questions/5737975/circle-drawing-with-svgs-arc-path
+			lwprint_double(radius*2, precision, sy);
+			stringbuffer_aprintf(sb, " m %s 0 a %s %s 0 1 0 -%s 0", sx, sx, sx, sy);
+			stringbuffer_aprintf(sb, " a %s %s 0 1 0 %s 0", sx, sx, sy);
+		}
+		else {
+			/* Arc radius radius 0 arcflag swipeflag */
+			if (relative){
+				stringbuffer_aprintf(sb, " a %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
+			}
+			else {
+				stringbuffer_aprintf(sb, " A %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
+			}
+			lwprint_double(t3->x, precision, sx);
+			lwprint_double(-(t3->y), precision, sy);
+			/* end point */
+			stringbuffer_aprintf(sb, "%s %s", sx, sy);
+		}
+	}
+}
+
+static void
+assvg_circstring(stringbuffer_t* sb, const LWCIRCSTRING *icurve, int relative, int precision)
+{
+	/* Start path with SVG MoveTo */
+	stringbuffer_append(sb, "M ");
+	pointArray_svg_arc(sb, icurve->points, 1, relative, precision);
 }
 
+static void
+assvg_compound(stringbuffer_t* sb, const LWCOMPOUND *icompound, int relative, int precision)
+{
+	uint32_t i;
+	LWGEOM *geom;
+	LWCIRCSTRING *tmpc = NULL;
+	LWLINE *tmpl = NULL;
+	/* Start path with SVG MoveTo */
+	stringbuffer_append(sb, "M ");
+
+	for (i = 0; i < icompound->ngeoms; i++)
+	{
+		if (i) stringbuffer_append(sb, " ");  /* SVG whitespace Separator */
+		geom = icompound->geoms[i];
+
+		switch (geom->type)
+		{
+			case CIRCSTRINGTYPE:
+				tmpc = (LWCIRCSTRING *)geom;
+				pointArray_svg_arc(sb, tmpc->points, 1, relative, precision);
+				break;
+
+			case LINETYPE:
+				tmpl = (LWLINE *)geom;
+
+				if (i){
+					/** if the compound curve does not start with a line,
+					 * we need to skip the first point since it is the same as previous
+					 * point of previous curve **/
+					if (relative)
+						pointArray_svg_rel(sb, tmpl->points, 1, precision, 1);
+					else
+						pointArray_svg_abs(sb, tmpl->points, 1, precision, 1);
+				}
+				else {
+					if (relative)
+						pointArray_svg_rel(sb, tmpl->points, 1, precision, 0);
+					else
+						pointArray_svg_abs(sb, tmpl->points, 1, precision, 0);
+				}
+				break;
+
+			default:
+				break; /** in theory this should never happen **/
+		}
+	}
+}
 
 static void
 assvg_polygon(stringbuffer_t* sb, const LWPOLY *poly, int relative, int precision)
@@ -164,18 +317,17 @@ assvg_polygon(stringbuffer_t* sb, const LWPOLY *poly, int relative, int precisio
 
 		if (relative)
 		{
-			pointArray_svg_rel(sb, poly->rings[i], 0, precision);
+			pointArray_svg_rel(sb, poly->rings[i], 0, precision, 0);
 			stringbuffer_append(sb, " z");	/* SVG closepath */
 		}
 		else
 		{
-			pointArray_svg_abs(sb, poly->rings[i], 0, precision);
+			pointArray_svg_abs(sb, poly->rings[i], 0, precision, 0);
 			stringbuffer_append(sb, " Z");	/* SVG closepath */
 		}
 	}
 }
 
-
 static void
 assvg_multipoint(stringbuffer_t* sb, const LWMPOINT *mpoint, int relative, int precision)
 {
@@ -205,7 +357,6 @@ assvg_multiline(stringbuffer_t* sb, const LWMLINE *mline, int relative, int prec
 	}
 }
 
-
 static void
 assvg_multipolygon(stringbuffer_t* sb, const LWMPOLY *mpoly, int relative, int precision)
 {
@@ -218,9 +369,104 @@ assvg_multipolygon(stringbuffer_t* sb, const LWMPOLY *mpoly, int relative, int p
 		poly = mpoly->geoms[i];
 		assvg_polygon(sb, poly, relative, precision);
 	}
+}
 
+static void
+assvg_multicurve(stringbuffer_t* sb, const LWMCURVE *mcurve, int relative, int precision)
+{
+	uint32_t i;
+	LWGEOM *geom;
+	const LWCIRCSTRING *tmpc = NULL;
+	const LWLINE *tmpl = NULL;
+
+	for (i = 0; i < mcurve->ngeoms; i++)
+	{
+		if (i) stringbuffer_append(sb, " ");  /* SVG whitespace Separator */
+		geom = mcurve->geoms[i];
+
+		switch (geom->type)
+		{
+			case CIRCSTRINGTYPE:
+				tmpc = (LWCIRCSTRING *)geom;
+				assvg_circstring(sb, tmpc, relative, precision);
+				break;
+
+			case LINETYPE:
+				tmpl = (LWLINE *)geom;
+				assvg_line(sb, tmpl, relative, precision);
+				break;
+
+			default:
+				break; /** in theory this should never happen **/
+		}
+	}
 }
 
+static void
+assvg_curvepoly(stringbuffer_t* sb, const LWCURVEPOLY *curvepoly, int relative, int precision)
+{
+	uint32_t i;
+	LWGEOM *tmp;
+
+	for (i = 0; i < curvepoly->nrings; i++)
+	{
+		if (i) stringbuffer_append(sb, " ");	/* Space between each ring */
+		tmp = curvepoly->rings[i];
+		switch (tmp->type)
+		{
+			case CIRCSTRINGTYPE:
+				assvg_circstring(sb, (LWCIRCSTRING *)tmp, relative, precision);
+				break;
+
+			case LINETYPE:
+				assvg_line(sb, (LWLINE *)tmp, relative, precision);
+				break;
+
+			case COMPOUNDTYPE:
+				assvg_compound(sb, (LWCOMPOUND *)tmp, relative, precision);
+				break;
+
+			default:
+				break; /** in theory this should never happen **/
+		}
+		if (relative)
+		{
+			stringbuffer_append(sb, " z");	/* SVG closepath */
+		}
+		else
+		{
+			stringbuffer_append(sb, " Z");	/* SVG closepath */
+		}
+	}
+}
+
+static void
+assvg_multisurface(stringbuffer_t* sb, const LWMSURFACE *msurface, int relative, int precision)
+{
+	LWGEOM *geom;
+	uint32_t i;
+	const LWPOLY *poly;
+	const LWCURVEPOLY *curvepoly;
+
+	for (i = 0; i < msurface->ngeoms; i++)
+	{
+		if (i) stringbuffer_append(sb, " ");  /* SVG whitespace Separator */
+		geom = msurface->geoms[i];
+		switch (geom->type)
+		{
+			case CURVEPOLYTYPE:
+				curvepoly = (LWCURVEPOLY *) geom;
+				assvg_curvepoly(sb, curvepoly, relative, precision);
+				break;
+			case POLYGONTYPE:
+				poly = (LWPOLY *) geom;
+				assvg_polygon(sb, poly, relative, precision);
+				break;
+			default:
+				break; /** in theory this should never happen **/
+		}
+	}
+}
 
 static void
 assvg_collection(stringbuffer_t* sb, const LWCOLLECTION *col, int relative, int precision)
@@ -279,6 +525,26 @@ assvg_geom(stringbuffer_t* sb, const LWGEOM *geom, int relative, int precision)
 		assvg_multipolygon(sb, (LWMPOLY*)geom, relative, precision);
 		break;
 
+	case CIRCSTRINGTYPE:
+		assvg_circstring(sb, (LWCIRCSTRING*)geom, relative, precision);
+		break;
+
+	case COMPOUNDTYPE:
+		assvg_compound(sb, (LWCOMPOUND*)geom, relative, precision);
+		break;
+
+	case CURVEPOLYTYPE:
+		assvg_curvepoly(sb, (LWCURVEPOLY*)geom, relative, precision);
+		break;
+
+	case MULTICURVETYPE:
+		assvg_multicurve(sb, (LWMCURVE*)geom, relative, precision);
+		break;
+
+	case MULTISURFACETYPE:
+		assvg_multisurface(sb, (LWMSURFACE*)geom, relative, precision);
+		break;
+
 	default:
 		lwerror("assvg_geom_buf: '%s' geometry type not supported.",
 		        lwtype_name(type));
@@ -286,9 +552,6 @@ assvg_geom(stringbuffer_t* sb, const LWGEOM *geom, int relative, int precision)
 
 }
 
-
-
-
 /**
  * Takes a GEOMETRY and returns a SVG representation
  */
@@ -319,15 +582,30 @@ lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
 	case POLYGONTYPE:
 		assvg_polygon(&sb, (LWPOLY*)geom, relative, precision);
 		break;
+	case CIRCSTRINGTYPE:
+		assvg_circstring(&sb, (LWCIRCSTRING*)geom, relative, precision);
+		break;
+	case COMPOUNDTYPE:
+		assvg_compound(&sb, (LWCOMPOUND*)geom, relative, precision);
+		break;
+	case CURVEPOLYTYPE:
+		assvg_curvepoly(&sb, (LWCURVEPOLY*)geom, relative, precision);
+		break;
 	case MULTIPOINTTYPE:
 		assvg_multipoint(&sb, (LWMPOINT*)geom, relative, precision);
 		break;
 	case MULTILINETYPE:
 		assvg_multiline(&sb, (LWMLINE*)geom, relative, precision);
 		break;
+	case MULTICURVETYPE:
+		assvg_multicurve(&sb, (LWMCURVE*)geom, relative, precision);
+		break;
 	case MULTIPOLYGONTYPE:
 		assvg_multipolygon(&sb, (LWMPOLY*)geom, relative, precision);
 		break;
+	case MULTISURFACETYPE:
+		assvg_multisurface(&sb, (LWMSURFACE*)geom, relative, precision);
+		break;
 	case COLLECTIONTYPE:
 		assvg_collection(&sb, (LWCOLLECTION*)geom, relative, precision);
 		break;

-----------------------------------------------------------------------

Summary of changes:
 NEWS                         |   2 +
 doc/reference_output.xml     |  43 +++++-
 liblwgeom/cunit/cu_out_svg.c |  56 ++++----
 liblwgeom/lwout_svg.c        | 308 ++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 365 insertions(+), 44 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list