[postgis-commits] svn - r2983 - trunk/liblwgeom
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Thu Sep 18 06:54:05 PDT 2008
Author: mcayland
Date: 2008-09-18 06:54:05 -0700 (Thu, 18 Sep 2008)
New Revision: 2983
Modified:
trunk/liblwgeom/lwgunparse.c
Log:
Update the code for unparsing LWGEOMs to WKB/WKT so that it includes the standard simple checks: LINESTRINGs must have > 2 points, POLYGONs must have closed rings and CIRCULARSTRINGs must have > 2 points and the number of points must be odd. There is still a little more work to do to allow flags to be passed into the parser to specify which checks should be enforced, much like has already been done for the parsing from WKB/WKT to LWGEOM.
Modified: trunk/liblwgeom/lwgunparse.c
===================================================================
--- trunk/liblwgeom/lwgunparse.c 2008-09-18 04:34:32 UTC (rev 2982)
+++ trunk/liblwgeom/lwgunparse.c 2008-09-18 13:54:05 UTC (rev 2983)
@@ -40,6 +40,10 @@
uchar* output_point(uchar* geom,int supress);
uchar* output_single(uchar* geom,int supress);
uchar* output_collection(uchar* geom,outfunc func,int supress);
+uchar* output_line_collection(uchar* geom,outfunc func,int supress);
+uchar* output_polygon_collection(uchar* geom,int suppress);
+uchar* output_polygon_ring_collection(uchar* geom,outfunc func,int supress);
+uchar* output_curve_collection(uchar* geom,outfunc func,int supress);
uchar* output_collection_2(uchar* geom,int suppress);
uchar* output_multipoint(uchar* geom,int suppress);
uchar* output_compound(uchar* geom, int suppress);
@@ -52,7 +56,10 @@
void write_wkb_int(int i);
uchar* output_wkb_collection(uchar* geom,outwkbfunc func);
-uchar* output_wkb_collection_2(uchar* geom);
+uchar* output_wkb_polygon_collection(uchar* geom);
+uchar* output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func);
+uchar* output_wkb_line_collection(uchar* geom,outwkbfunc func);
+uchar* output_wkb_curve_collection(uchar* geom,outwkbfunc func);
uchar* output_wkb_point(uchar* geom);
uchar* output_wkb(uchar* geom);
@@ -195,6 +202,7 @@
return geom;
}
+/* Output a standard collection */
uchar *
output_collection(uchar* geom,outfunc func,int supress)
{
@@ -215,12 +223,121 @@
return geom;
}
+/* Output a set of LINESTRING points */
uchar *
-output_collection_2(uchar* geom,int suppress)
+output_line_collection(uchar* geom,outfunc func,int supress)
{
- return output_collection(geom,output_point,suppress);
+ int cnt = read_int(&geom);
+
+ /* Ensure that LINESTRING has a minimum of 2 points */
+ if (cnt < 2)
+ lwerror("geometry requires more points");
+
+ if ( cnt == 0 ){
+ write_str(" EMPTY");
+ }
+ else{
+ write_str("(");
+ while(cnt--){
+ geom=func(geom,supress);
+ if ( cnt ){
+ write_str(",");
+ }
+ }
+ write_str(")");
+ }
+ return geom;
}
+/* Output an individual ring from a POLYGON */
+uchar *
+output_polygon_ring_collection(uchar* geom,outfunc func,int supress)
+{
+ uchar *temp;
+ int dimcount;
+ double first_point[dims];
+ double last_point[dims];
+
+ int cnt = read_int(&geom);
+ if ( cnt == 0 ){
+ write_str(" EMPTY");
+ }
+ else{
+ write_str("(");
+
+ /* Store the first point of the ring (use a temp var since read_double alters
+ the pointer after use) */
+ temp = geom;
+ dimcount = 0;
+ while (dimcount < dims)
+ {
+ first_point[dimcount] = read_double(&temp);
+ dimcount++;
+ }
+
+ while(cnt--){
+ geom=func(geom,supress);
+ if ( cnt ){
+ write_str(",");
+ }
+ }
+ write_str(")");
+
+ /* Store the last point of the ring (note: we will have moved past it, so we
+ need to count backwards) */
+ temp = geom - sizeof(double) * dims;
+ dimcount = 0;
+ while (dimcount < dims)
+ {
+ last_point[dimcount] = read_double(&temp);
+ dimcount++;
+ }
+
+ /* Check if they are the same... */
+ if (memcmp(&first_point, &last_point, sizeof(double) * dims))
+ lwerror("geometry contains non-closed rings");
+
+ }
+ return geom;
+}
+
+/* Ouput the points from a CIRCULARSTRING */
+uchar *
+output_curve_collection(uchar* geom,outfunc func,int supress)
+{
+ int cnt = read_int(&geom);
+
+ /* Ensure that a CIRCULARSTRING has a minimum of 3 points */
+ if (cnt < 3)
+ lwerror("geometry requires more points");
+
+ /* Ensure that a CIRCULARSTRING has an odd number of points */
+ if (cnt % 2 != 1)
+ lwerror("geometry must have an odd number of points");
+
+ if ( cnt == 0 ){
+ write_str(" EMPTY");
+ }
+ else{
+ write_str("(");
+ while(cnt--){
+ geom=func(geom,supress);
+ if ( cnt ){
+ write_str(",");
+ }
+ }
+ write_str(")");
+ }
+ return geom;
+}
+
+/* Output a POLYGON consisting of a number of rings */
+uchar *
+output_polygon_collection(uchar* geom,int suppress)
+{
+ return output_polygon_ring_collection(geom,output_point,suppress);
+}
+
uchar *output_wkt(uchar* geom, int supress);
/* special case for multipoint to supress extra brackets */
@@ -253,7 +370,7 @@
break;
case CURVETYPE:
write_str("CIRCULARSTRING");
- geom = output_collection(geom,output_point,1);
+ geom = output_curve_collection(geom,output_point,1);
break;
}
return geom;
@@ -268,7 +385,7 @@
switch(TYPE_GETTYPE(type))
{
case POLYGONTYPE:
- geom = output_collection(geom, output_collection_2,0);
+ geom = output_collection(geom, output_polygon_collection,0);
break;
case CURVEPOLYTYPE:
write_str("CURVEPOLYGON");
@@ -321,7 +438,7 @@
if (writeM) write_str("LINESTRINGM");
else write_str("LINESTRING");
}
- geom = output_collection(geom,output_point,0);
+ geom = output_line_collection(geom,output_point,0);
break;
case CURVETYPE:
if ( supress < 2 )
@@ -329,7 +446,7 @@
if(writeM) write_str("CIRCULARSTRINGM");
else write_str("CIRCULARSTRING");
}
- geom = output_collection(geom,output_point,0);
+ geom = output_curve_collection(geom,output_point,0);
break;
case POLYGONTYPE:
if ( supress < 2 )
@@ -337,7 +454,7 @@
if (writeM) write_str("POLYGONM");
else write_str("POLYGON");
}
- geom = output_collection(geom,output_collection_2,0);
+ geom = output_collection(geom,output_polygon_collection,0);
break;
case COMPOUNDTYPE:
if ( supress < 2 )
@@ -431,7 +548,7 @@
else write_str("POLYGON");
}
lwgi++;
- geom =output_collection(geom,output_collection_2,0);
+ geom = output_collection(geom,output_polygon_collection,0);
lwgi--;
break;
}
@@ -548,6 +665,7 @@
write_wkb_bytes((uchar*)&i,1,4);
}
+/* Output a standard collection */
uchar *
output_wkb_collection(uchar* geom,outwkbfunc func)
{
@@ -560,12 +678,98 @@
return geom;
}
+/* Output a set of LINESTRING points */
uchar *
-output_wkb_collection_2(uchar* geom){
- return output_wkb_collection(geom,output_wkb_point);
+output_wkb_line_collection(uchar* geom,outwkbfunc func)
+{
+ int cnt = read_int(&geom);
+
+ LWDEBUGF(2, "output_wkb_line_collection: %d iterations loop", cnt);
+
+ /* Ensure that LINESTRING has a minimum of 2 points */
+ if (cnt < 2)
+ lwerror("geometry requires more points");
+
+ write_wkb_int(cnt);
+ while(cnt--) geom=func(geom);
+ return geom;
}
+/* Output an individual ring from a POLYGON */
uchar *
+output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func)
+{
+ uchar *temp;
+ int dimcount;
+ double first_point[dims];
+ double last_point[dims];
+
+ int cnt = read_int(&geom);
+
+ LWDEBUGF(2, "output_wkb_polygon_ring_collection: %d iterations loop", cnt);
+
+ write_wkb_int(cnt);
+
+ /* Store the first point of the ring (use a temp var since read_double alters
+ the pointer after use) */
+ temp = geom;
+ dimcount = 0;
+ while (dimcount < dims)
+ {
+ first_point[dimcount] = read_double(&temp);
+ dimcount++;
+ }
+
+ while(cnt--) geom=func(geom);
+
+ /* Store the last point of the ring (note: we will have moved past it, so we
+ need to count backwards) */
+ temp = geom - sizeof(double) * dims;
+ dimcount = 0;
+ while (dimcount < dims)
+ {
+ last_point[dimcount] = read_double(&temp);
+ dimcount++;
+ }
+
+ /* Check if they are the same... */
+ if (memcmp(&first_point, &last_point, sizeof(double) * dims))
+ lwerror("geometry contains non-closed rings");
+
+ return geom;
+}
+
+/* Output a POLYGON consisting of a number of rings */
+uchar *
+output_wkb_polygon_collection(uchar* geom)
+{
+ LWDEBUGF(2, "output_wkb_polygon_collection: %d iterations loop", cnt);
+
+ return output_wkb_polygon_ring_collection(geom,output_wkb_point);
+}
+
+/* Ouput the points from a CIRCULARSTRING */
+uchar *
+output_wkb_curve_collection(uchar* geom,outwkbfunc func)
+{
+ int cnt = read_int(&geom);
+
+ LWDEBUGF(2, "output_wkb_curve_collection: %d iterations loop", cnt);
+
+ /* Ensure that a CIRCULARSTRING has a minimum of 3 points */
+ if (cnt < 3)
+ lwerror("geometry requires more points");
+
+ /* Ensure that a CIRCULARSTRING has an odd number of points */
+ if (cnt % 2 != 1)
+ lwerror("geometry must have an odd number of points");
+
+ write_wkb_int(cnt);
+ while(cnt--) geom=func(geom);
+ return geom;
+}
+
+uchar *
output_wkb(uchar* geom)
{
unsigned char type=*geom++;
@@ -605,13 +809,13 @@
geom=output_wkb_point(geom);
break;
case LINETYPE:
- geom=output_wkb_collection(geom,output_wkb_point);
+ geom=output_wkb_line_collection(geom,output_wkb_point);
break;
case CURVETYPE:
- geom=output_wkb_collection(geom,output_wkb_point);
+ geom=output_wkb_curve_collection(geom,output_wkb_point);
break;
case POLYGONTYPE:
- geom=output_wkb_collection(geom,output_wkb_collection_2);
+ geom=output_wkb_collection(geom,output_wkb_polygon_collection);
break;
case COMPOUNDTYPE:
geom=output_wkb_collection(geom,output_wkb);
@@ -648,7 +852,7 @@
break;
case POLYGONTYPEI:
lwgi++;
- geom = output_wkb_collection(geom,output_wkb_collection_2);
+ geom = output_wkb_collection(geom,output_wkb_polygon_collection);
lwgi--;
break;
}
More information about the postgis-commits
mailing list