/********************************************************************** * $Id$ * * PostGIS - Spatial Types for PostgreSQL * http://postgis.net * Copyright 2010 Olivier Courtin * * This is free software; you can redistribute and/or modify it under * the terms of the GNU General Public Licence. See the COPYING file. * **********************************************************************/ #include #include #include #include "CUnit/Basic.h" #include "liblwgeom_internal.h" #include "cu_tester.h" static void do_geojson_test(char * in, char * out, char * srs, int precision, int has_bbox) { LWGEOM *g; char * h; g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); h = lwgeom_to_geojson(g, srs, precision, has_bbox); if (strcmp(h, out)) fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); lwfree(h); } static void do_geojson_unsupported(char * in, char * out) { LWGEOM *g; char *h; g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); h = lwgeom_to_geojson(g, NULL, 0, 0); if (strcmp(cu_error_msg, out)) fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, cu_error_msg, out); CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); lwfree(h); lwgeom_free(g); } static void out_geojson_test_precision(void) { /* 0 precision, i.e a round */ do_geojson_test( "POINT(1.1111111111111 1.1111111111111)", "{\"type\":\"Point\",\"coordinates\":[1,1]}", NULL, 0, 0); /* 3 digits precision */ do_geojson_test( "POINT(1.1111111111111 1.1111111111111)", "{\"type\":\"Point\",\"coordinates\":[1.111,1.111]}", NULL, 3, 0); /* 9 digits precision */ do_geojson_test( "POINT(1.2345678901234 1.2345678901234)", "{\"type\":\"Point\",\"coordinates\":[1.23456789,1.23456789]}", NULL, 9, 0); /* huge data */ do_geojson_test( "POINT(1E300 -1E300)", "{\"type\":\"Point\",\"coordinates\":[1e+300,-1e+300]}", NULL, 0, 0); /* huge precision, see http://trac.osgeo.org/postgis/ticket/2052 */ do_geojson_test( "POINT(1 2)", "{\"type\":\"Point\",\"coordinates\":[1,2]}", NULL, 100, 0); /* double precision, see http://trac.osgeo.org/postgis/ticket/2051 */ do_geojson_test( "POINT(59.99 -59.99)", "{\"type\":\"Point\",\"coordinates\":[59.99,-59.99]}", NULL, 15, 0); /* small numbers */ /* NOTE: precision of 300 will be converted to max precision (15) * and being there no significant digit within that range * only zeroes will be returned * See http://trac.osgeo.org/postgis/ticket/2051#comment:11 */ do_geojson_test( "POINT(1E-300 -2E-200)", "{\"type\":\"Point\",\"coordinates\":[0,-0]}", NULL, 300, 0); } static void out_geojson_test_dims(void) { /* 3D */ do_geojson_test( "POINT(0 1 2)", "{\"type\":\"Point\",\"coordinates\":[0,1,2]}", NULL, 0, 0); /* 3DM */ do_geojson_test( "POINTM(0 1 2)", "{\"type\":\"Point\",\"coordinates\":[0,1]}", NULL, 0, 0); /* 4D */ do_geojson_test( "POINT(0 1 2 3)", "{\"type\":\"Point\",\"coordinates\":[0,1,2]}", NULL, 0, 0); } static void out_geojson_test_srid(void) { /* Linestring */ do_geojson_test( "LINESTRING(0 1,2 3,4 5)", "{\"type\":\"LineString\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[0,1],[2,3],[4,5]]}", "EPSG:4326", 0, 0); /* Polygon */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1))", "{\"type\":\"Polygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}", "EPSG:4326", 0, 0); /* Polygon - with internal ring */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))", "{\"type\":\"Polygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}", "EPSG:4326", 0, 0); /* Multiline */ do_geojson_test( "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))", "{\"type\":\"MultiLineString\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}", "EPSG:4326", 0, 0); /* MultiPolygon */ do_geojson_test( "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))", "{\"type\":\"MultiPolygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}", "EPSG:4326", 0, 0); /* GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))", "{\"type\":\"GeometryCollection\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"geometries\":[{\"type\":\"Point\",\"coordinates\":[0,1]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}", "EPSG:4326", 0, 0); /* Empty GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION EMPTY", "{\"type\":\"GeometryCollection\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"geometries\":[]}", "EPSG:4326", 0, 0); } static void out_geojson_test_bbox(void) { /* Linestring */ do_geojson_test( "LINESTRING(0 1,2 3,4 5)", "{\"type\":\"LineString\",\"bbox\":[0,1,4,5],\"coordinates\":[[0,1],[2,3],[4,5]]}", NULL, 0, 1); /* Polygon */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1))", "{\"type\":\"Polygon\",\"bbox\":[0,1,4,5],\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}", NULL, 0, 1); /* Polygon - with internal ring */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))", "{\"type\":\"Polygon\",\"bbox\":[0,1,4,5],\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}", NULL, 0, 1); /* Multiline */ do_geojson_test( "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))", "{\"type\":\"MultiLineString\",\"bbox\":[0,1,10,11],\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}", NULL, 0, 1); /* MultiPolygon */ do_geojson_test( "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))", "{\"type\":\"MultiPolygon\",\"bbox\":[0,1,10,11],\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}", NULL, 0, 1); /* GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION(LINESTRING(0 1,-1 3),LINESTRING(2 3,4 5))", "{\"type\":\"GeometryCollection\",\"bbox\":[-1,1,4,5],\"geometries\":[{\"type\":\"LineString\",\"coordinates\":[[0,1],[-1,3]]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}", NULL, 0, 1); /* Empty GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION EMPTY", "{\"type\":\"GeometryCollection\",\"geometries\":[]}", NULL, 0, 1); } static void out_geojson_test_geoms(void) { /* Linestring */ do_geojson_test( "LINESTRING(0 1,2 3,4 5)", "{\"type\":\"LineString\",\"coordinates\":[[0,1],[2,3],[4,5]]}", NULL, 0, 0); /* Polygon */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1))", "{\"type\":\"Polygon\",\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}", NULL, 0, 0); /* Polygon - with internal ring */ do_geojson_test( "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))", "{\"type\":\"Polygon\",\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}", NULL, 0, 0); /* Multiline */ do_geojson_test( "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))", "{\"type\":\"MultiLineString\",\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}", NULL, 0, 0); /* MultiPolygon */ do_geojson_test( "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))", "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}", NULL, 0, 0); /* GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))", "{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[0,1]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}", NULL, 0, 0); /* Empty GeometryCollection */ do_geojson_test( "GEOMETRYCOLLECTION EMPTY", "{\"type\":\"GeometryCollection\",\"geometries\":[]}", NULL, 0, 0); /* Nested GeometryCollection */ do_geojson_unsupported( "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))", "GeoJson: geometry not supported."); /* CircularString */ do_geojson_unsupported( "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)", "lwgeom_to_geojson: 'CircularString' geometry type not supported"); /* CompoundCurve */ do_geojson_unsupported( "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))", "lwgeom_to_geojson: 'CompoundCurve' geometry type not supported"); /* CurvePolygon */ do_geojson_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_geojson: 'CurvePolygon' geometry type not supported"); /* MultiCurve */ do_geojson_unsupported( "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))", "lwgeom_to_geojson: 'MultiCurve' geometry type not supported"); /* MultiSurface */ do_geojson_unsupported( "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_geojson: 'MultiSurface' geometry type not supported"); } /* ** Used by test harness to register the tests in this file. */ void out_geojson_suite_setup(void); void out_geojson_suite_setup(void) { CU_pSuite suite = CU_add_suite("geojson_output", NULL, NULL); PG_ADD_TEST(suite, out_geojson_test_precision); PG_ADD_TEST(suite, out_geojson_test_dims); PG_ADD_TEST(suite, out_geojson_test_srid); PG_ADD_TEST(suite, out_geojson_test_bbox); PG_ADD_TEST(suite, out_geojson_test_geoms); }