<Shape>
<Appearance>
<Material emissiveColor='0 0 1'/>
- </Appearance> <IndexedFaceSet coordIndex='0 1 2 3 -1 4 5 6 7 -1 8 9 10 11 -1 12 13 14 15 -1 16 17 18 19 -1 20 21 22 23'><Coordinate point='0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1' /></IndexedFaceSet></Shape>
+ </Appearance>
+ <IndexedFaceSet coordIndex='0 1 2 3 -1 4 5 6 7 -1 8 9 10 11 -1 12 13 14 15 -1 16 17 18 19 -1 20 21 22 23'>
+ <Coordinate point='0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1' />
+ </IndexedFaceSet>
+ </Shape>
</Transform>
</Scene>
</X3D>]]></programlisting>
--------
<![CDATA[<IndexedTriangleSet index='0 1 2 3 4 5'><Coordinate point='0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0'/></IndexedTriangleSet>]]></programlisting>
</refsection>
+ <refsection>
+ <title>Example: Closed multilinestring (the boundary of a polygon with holes)</title>
+ <programlisting><![CDATA[SELECT ST_AsX3D(
+ ST_GeomFromEWKT('MULTILINESTRING((20 0 10,16 -12 10,0 -16 10,-12 -12 10,-20 0 10,-12 16 10,0 24 10,16 16 10,20 0 10),
+ (12 0 10,8 8 10,0 12 10,-8 8 10,-8 0 10,-8 -4 10,0 -8 10,8 -4 10,12 0 10))')
+) As x3dfrag;]]>
+
+ x3dfrag
+ --------
+<![CDATA[<IndexedLineSet coordIndex='0 1 2 3 4 5 6 7 0 -1 8 9 10 11 12 13 14 15 8'>
+ <Coordinate point='20 0 10 16 -12 10 0 -16 10 -12 -12 10 -20 0 10 -12 16 10 0 24 10 16 16 10 12 0 10 8 8 10 0 12 10 -8 8 10 -8 0 10 -8 -4 10 0 -8 10 8 -4 10 ' />
+ </IndexedLineSet>]]></programlisting>
+ </refsection>
</refentry>
<refentry id="ST_GeoHash">
static char *asx3d3_tin(const LWTIN *tin, char *srs, int precision, int opts, const char *defid);\r
static size_t asx3d3_collection_size(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid);\r
static char *asx3d3_collection(const LWCOLLECTION *col, char *srs, int precision, int opts, const char *defid);\r
-static size_t pointArray_toX3D3(POINTARRAY *pa, char *buf, int precision, int opts, int type);\r
+static size_t pointArray_toX3D3(POINTARRAY *pa, char *buf, int precision, int opts, int is_closed);\r
\r
static size_t pointArray_X3Dsize(POINTARRAY *pa, int precision);\r
\r
//ptr += sprintf(ptr, "%s", defid);\r
\r
//ptr += sprintf(ptr, "<%spos>", defid);\r
- ptr += pointArray_toX3D3(point->point, ptr, precision, opts, point->type);\r
+ ptr += pointArray_toX3D3(point->point, ptr, precision, opts, 0);\r
//ptr += sprintf(ptr, "</%spos></%sPoint>", defid, defid);\r
\r
return (ptr-output);\r
\r
\r
ptr += sprintf(ptr, "<Coordinate point='");\r
- ptr += pointArray_toX3D3(line->points, ptr, precision, opts, line->type);\r
+ ptr += pointArray_toX3D3(line->points, ptr, precision, opts, lwline_is_closed(line));\r
\r
ptr += sprintf(ptr, "' />");\r
\r
char *ptr=output;\r
\r
ptr += sprintf(ptr, "");\r
- ptr += pointArray_toX3D3(line->points, ptr, precision, opts, line->type);\r
+ ptr += pointArray_toX3D3(line->points, ptr, precision, opts, lwline_is_closed(line));\r
return (ptr-output);\r
}\r
\r
/* Calculate the coordIndex property of the IndexedLineSet for the multilinestring */\r
static size_t\r
-asx3d3_mline_coordindex(const LWCOLLECTION *mgeom, char *output)\r
+asx3d3_mline_coordindex(const LWMLINE *mgeom, char *output)\r
{\r
char *ptr=output;\r
LWLINE *geom;\r
- int i, j, k;\r
+ int i, j, k, si;\r
POINTARRAY *pa;\r
int np;\r
\r
{\r
geom = (LWLINE *) mgeom->geoms[i];\r
pa = geom->points;\r
- np = pa->npoints - 1;\r
+ np = pa->npoints;\r
+ si = j; //start index of first point of linestring\r
for(k=0; k < np ; k++){\r
if (k) {\r
ptr += sprintf(ptr, " "); \r
}\r
- ptr += sprintf(ptr, "%d", (j + k));\r
+ /** if the linestring is closed, we put the start point index \r
+ * for the last vertex to denote use first point\r
+ * and don't increment the index **/\r
+ if (!lwline_is_closed(geom) || k < (np -1) ){\r
+ ptr += sprintf(ptr, "%d", j);\r
+ j += 1;\r
+ }\r
+ else { \r
+ ptr += sprintf(ptr,"%d", si);\r
+ }\r
}\r
if (i < (mgeom->ngeoms - 1) ){\r
- ptr += sprintf(ptr, " -1 "); //separator for each subgeom\r
+ ptr += sprintf(ptr, " -1 "); //separator for each linestring\r
}\r
- j += k;\r
}\r
return (ptr-output);\r
}\r
int dimension=2;\r
\r
if (FLAGS_GET_Z(poly->flags)) dimension = 3;\r
- ptr += pointArray_toX3D3(poly->rings[0], ptr, precision, opts, poly->type);\r
+ ptr += pointArray_toX3D3(poly->rings[0], ptr, precision, opts, 1);\r
for (i=1; i<poly->nrings; i++)\r
{\r
- ptr += pointArray_toX3D3(poly->rings[i], ptr, precision, opts, poly->type);\r
+ ptr += pointArray_toX3D3(poly->rings[i], ptr, precision, opts,1);\r
ptr += sprintf(ptr, " ");\r
}\r
return (ptr-output);\r
asx3d3_triangle_buf(const LWTRIANGLE *triangle, char *srs, char *output, int precision, int opts, const char *defid)\r
{\r
char *ptr=output;\r
- ptr += pointArray_toX3D3(triangle->points, ptr, precision, opts, triangle->type);\r
+ ptr += pointArray_toX3D3(triangle->points, ptr, precision, opts, 1);\r
\r
return (ptr-output);\r
}\r
/* In X3D3, coordinates are separated by a space separator\r
*/\r
static size_t\r
-pointArray_toX3D3(POINTARRAY *pa, char *output, int precision, int opts, int type)\r
+pointArray_toX3D3(POINTARRAY *pa, char *output, int precision, int opts, int is_closed)\r
{\r
int i;\r
char *ptr;\r
for (i=0; i<pa->npoints; i++)\r
{\r
/** Only output the point if it is not the last point of a closed object or it is a non-closed type **/\r
- if (!(type == POLYGONTYPE || type == TRIANGLETYPE) || i < (pa->npoints - 1) ){\r
+ if ( !is_closed || i < (pa->npoints - 1) ){\r
POINT2D pt;\r
getPoint2d_p(pa, i, &pt);\r
\r
for (i=0; i<pa->npoints; i++)\r
{\r
/** Only output the point if it is not the last point of a closed object or it is a non-closed type **/\r
- if (!(type == POLYGONTYPE || type == TRIANGLETYPE) || i < (pa->npoints - 1) ){\r
+ if ( !is_closed || i < (pa->npoints - 1) ){\r
POINT4D pt;\r
getPoint4d_p(pa, i, &pt);\r
\r