Changeset: 015ab48b1726 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=015ab48b1726
Added Files:
geom/monetdb5/geom_geojson.c
geom/monetdb5/geom_x3d.c
Modified Files:
geom/monetdb5/Makefile.ag
Branch: sfcgal
Log Message:
Add functions to generate X3D and GeoJson. The functions were not yet heavly
tested. Add them to the Makefile
diffs (truncated from 1554 to 300 lines):
diff --git a/geom/monetdb5/Makefile.ag b/geom/monetdb5/Makefile.ag
--- a/geom/monetdb5/Makefile.ag
+++ b/geom/monetdb5/Makefile.ag
@@ -16,7 +16,7 @@ INCLUDES = ../lib \
lib__geom = {
MODULE
DIR = libdir/monetdb5
- SOURCES = geom.h geom.c geomBulk.c geom_upgrade.c
+ SOURCES = geom.h geom.c geomBulk.c geom_upgrade.c geom_geojson.c
geom_x3d.c
LIBS = ../lib/libgeom \
../../gdk/libbat \
../../common/stream/libstream \
diff --git a/geom/monetdb5/geom_geojson.c b/geom/monetdb5/geom_geojson.c
new file mode 100644
--- /dev/null
+++ b/geom/monetdb5/geom_geojson.c
@@ -0,0 +1,712 @@
+#include "geom.h"
+
+static char *asgeojson_point(GEOSGeom point, char *srs, bbox3D *bbox, int
precision);
+static char *asgeojson_line(GEOSGeom line, char *srs, bbox3D *bbox, int
precision);
+static char *asgeojson_poly(GEOSGeom poly, char *srs, bbox3D *bbox, int
precision);
+static char * asgeojson_multipoint(GEOSGeom mpoint, char *srs, bbox3D *bbox,
int precision);
+static char * asgeojson_multiline(GEOSGeom mline, char *srs, bbox3D *bbox, int
precision);
+static char * asgeojson_multipolygon(GEOSGeom mpoly, char *srs, bbox3D *bbox,
int precision);
+static char * asgeojson_collection(GEOSGeom col, char *srs, bbox3D *bbox, int
precision);
+static size_t asgeojson_geom_size(GEOSGeom geom, bbox3D *bbox, int precision);
+static size_t asgeojson_geom_buf(GEOSGeom geom, char *output, bbox3D *bbox,
int precision);
+
+static size_t points_to_geojson(GEOSGeom geom, char *buf, int precision);
+static size_t points_geojson_size(GEOSGeom geom, int precision);
+static void trim_trailing_zeros(char *str);
+
+#define BUFSIZE OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION
+
+char*
+geom_to_geojson(GEOSGeom geom, char *srs, int precision, int has_bbox)
+{
+ int type = GEOSGeomTypeId(geom)+1;
+ bbox3D *bbox;
+
+ if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision =
OUT_MAX_DOUBLE_PRECISION;
+
+ if (has_bbox)
+ {
+ bbox3DFromGeos(&bbox, geom);
+ }
+
+ switch (type)
+ {
+ case wkbPoint_mdb:
+ return asgeojson_point(geom, srs, bbox, precision);
+ case wkbLineString_mdb:
+ return asgeojson_line(geom, srs, bbox, precision);
+ case wkbPolygon_mdb:
+ return asgeojson_poly(geom, srs, bbox, precision);
+ case wkbMultiPoint_mdb:
+ return asgeojson_multipoint(geom, srs, bbox, precision);
+ case wkbMultiLineString_mdb:
+ return asgeojson_multiline(geom, srs, bbox, precision);
+ case wkbMultiPolygon_mdb:
+ return asgeojson_multipolygon(geom, srs, bbox, precision);
+ case wkbGeometryCollection_mdb:
+ return asgeojson_collection(geom, srs, bbox, precision);
+ default:
+ assert(0);
+ return NULL;
+ }
+
+ return NULL;
+}
+
+ static size_t
+asgeojson_srs_size(char *srs)
+{
+ int size;
+
+ size = sizeof("'crs':{'type':'name',");
+ size += sizeof("'properties':{'name':''}},");
+ size += strlen(srs) * sizeof(char);
+
+ return size;
+}
+
+ static size_t
+asgeojson_srs_buf(char *output, char *srs)
+{
+ char *ptr = output;
+
+ ptr += sprintf(ptr, "\"crs\":{\"type\":\"name\",");
+ ptr += sprintf(ptr, "\"properties\":{\"name\":\"%s\"}},", srs);
+
+ return (ptr-output);
+}
+
+ static size_t
+asgeojson_bbox_size(int hasz, int precision)
+{
+ int size;
+
+ if (!hasz)
+ {
+ size = sizeof("\"bbox\":[,,,],");
+ size += 2 * 2 * (OUT_MAX_DIGS_DOUBLE + precision);
+ }
+ else
+ {
+ size = sizeof("\"bbox\":[,,,,,],");
+ size += 2 * 3 * (OUT_MAX_DIGS_DOUBLE + precision);
+ }
+
+ return size;
+}
+
+ static size_t
+asgeojson_bbox_buf(char *output, bbox3D *bbox, int hasz, int precision)
+{
+ char *ptr = output;
+
+ if (!hasz)
+ ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f],",
+ precision, bbox->xmin, precision, bbox->ymin,
+ precision, bbox->xmax, precision, bbox->ymax);
+ else
+ ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f,%.*f,%.*f],",
+ precision, bbox->xmin, precision, bbox->ymin, precision,
bbox->zmin,
+ precision, bbox->xmax, precision, bbox->ymax, precision,
bbox->zmax);
+
+ return (ptr-output);
+}
+
+ static size_t
+asgeojson_point_size(GEOSGeom point, char *srs, bbox3D *bbox, int precision)
+{
+ int size;
+
+ size = points_geojson_size(point, precision);
+ size += sizeof("{'type':'Point',");
+ size += sizeof("'coordinates':}");
+
+ if ( GEOSisEmpty(point) == 1 )
+ size += 2; /* [] */
+
+ if (srs) size += asgeojson_srs_size(srs);
+ if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(point) == 3,
precision);
+
+ return size;
+}
+
+ static size_t
+asgeojson_point_buf(GEOSGeom point, char *srs, char *output, bbox3D *bbox, int
precision)
+{
+ char *ptr = output;
+
+ ptr += sprintf(ptr, "{\"type\":\"Point\",");
+ if (srs) ptr += asgeojson_srs_buf(ptr, srs);
+ if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox,
GEOS_getWKBOutputDims(point) == 3, precision);
+
+ ptr += sprintf(ptr, "\"coordinates\":");
+ if ( GEOSisEmpty(point) == 1 )
+ ptr += sprintf(ptr, "[]");
+ ptr += points_to_geojson(point, ptr, precision);
+ ptr += sprintf(ptr, "}");
+
+ return (ptr-output);
+}
+
+ static char *
+asgeojson_point(GEOSGeom point, char *srs, bbox3D *bbox, int precision)
+{
+ char *output;
+ int size;
+
+ size = asgeojson_point_size(point, srs, bbox, precision);
+ output = GDKmalloc(size);
+ asgeojson_point_buf(point, srs, output, bbox, precision);
+ return output;
+}
+
+ static size_t
+asgeojson_line_size(GEOSGeom line, char *srs, bbox3D *bbox, int precision)
+{
+ int size;
+
+ size = sizeof("{'type':'LineString',");
+ if (srs) size += asgeojson_srs_size(srs);
+ if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(line) == 3,
precision);
+ size += sizeof("'coordinates':[]}");
+ size += points_geojson_size(line, precision);
+
+ return size;
+}
+
+ static size_t
+asgeojson_line_buf(GEOSGeom line, char *srs, char *output, bbox3D *bbox, int
precision)
+{
+ char *ptr=output;
+
+ ptr += sprintf(ptr, "{\"type\":\"LineString\",");
+ if (srs) ptr += asgeojson_srs_buf(ptr, srs);
+ if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, GEOS_getWKBOutputDims(line)
== 3, precision);
+ ptr += sprintf(ptr, "\"coordinates\":[");
+ ptr += points_to_geojson(line, ptr, precision);
+ ptr += sprintf(ptr, "]}");
+
+ return (ptr-output);
+}
+
+ static char *
+asgeojson_line(GEOSGeom line, char *srs, bbox3D *bbox, int precision)
+{
+ char *output;
+ int size;
+
+ size = asgeojson_line_size(line, srs, bbox, precision);
+ output = GDKmalloc(size);
+ asgeojson_line_buf(line, srs, output, bbox, precision);
+
+ return output;
+}
+
+ static size_t
+asgeojson_poly_size(GEOSGeom poly, char *srs, bbox3D *bbox, int precision)
+{
+ size_t size;
+ int i, nrings = GEOSGetNumInteriorRings(poly);
+
+ size = sizeof("{\"type\":\"Polygon\",");
+ if (srs) size += asgeojson_srs_size(srs);
+ if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(poly) == 3,
precision);
+ size += sizeof("\"coordinates\":[");
+ for (i=0; i<nrings; i++)
+ {
+ size += points_geojson_size(*(GEOSGeom*)GEOSGetInteriorRingN(poly, i),
precision);
+ size += sizeof("[]");
+ }
+ size += sizeof(",") * i;
+ size += sizeof("]}");
+
+ return size;
+}
+
+ static size_t
+asgeojson_poly_buf(GEOSGeom poly, char *srs, char *output, bbox3D *bbox, int
precision)
+{
+ int i, nrings = GEOSGetNumInteriorRings(poly);
+ char *ptr=output;
+
+ ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
+ if (srs) ptr += asgeojson_srs_buf(ptr, srs);
+ if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, GEOS_getWKBOutputDims(poly)
== 3, precision);
+ ptr += sprintf(ptr, "\"coordinates\":[");
+ for (i=0; i<nrings; i++)
+ {
+ if (i) ptr += sprintf(ptr, ",");
+ ptr += sprintf(ptr, "[");
+ ptr += points_to_geojson(*(GEOSGeom*) GEOSGetInteriorRingN(poly, i),
ptr, precision);
+ ptr += sprintf(ptr, "]");
+ }
+ ptr += sprintf(ptr, "]}");
+
+ return (ptr-output);
+}
+
+ static char *
+asgeojson_poly(GEOSGeom poly, char *srs, bbox3D *bbox, int precision)
+{
+ char *output;
+ int size;
+
+ size = asgeojson_poly_size(poly, srs, bbox, precision);
+ output = GDKmalloc(size);
+ asgeojson_poly_buf(poly, srs, output, bbox, precision);
+
+ return output;
+}
+
+ static size_t
+asgeojson_multipoint_size(GEOSGeom mpoint, char *srs, bbox3D *bbox, int
precision)
+{
+ GEOSGeom point;
+ int size;
+ int i, ngeoms = GEOSGetNumGeometries(mpoint);
+
+ size = sizeof("{'type':'MultiPoint',");
+ if (srs) size += asgeojson_srs_size(srs);
+ if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(mpoint) == 3,
precision);
+ size += sizeof("'coordinates':[]}");
+
+ for (i=0; i<ngeoms; i++)
+ {
+ point = (GEOSGeom ) GEOSGetGeometryN(mpoint, i);
+ size += points_geojson_size(point, precision);
+ }
+ size += sizeof(",") * i;
+
+ return size;
+}
+
+ static size_t
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list