30 #include "../postgis_config.h" 32 #if defined(HAVE_LIBJSON) || defined(HAVE_LIBJSON_C) 34 #define JSON_C_VERSION_013 (13 << 8) 37 #include <json-c/json.h> 38 #if !defined(JSON_C_VERSION_NUM) || JSON_C_VERSION_NUM < JSON_C_VERSION_013 39 #include <json-c/json_object_private.h> 42 #include <json/json.h> 43 #if !defined(JSON_C_VERSION_NUM) || JSON_C_VERSION_NUM < JSON_C_VERSION_013 44 #include <json/json_object_private.h> 48 #ifndef JSON_C_VERSION 50 # define json_tokener_error_desc(x) json_tokener_errors[(x)] 57 LWDEBUGF(3,
"lwgeom_from_geojson ERROR %i", error_code);
72 if( NULL == pszName || NULL == poObj)
79 if( NULL != json_object_get_object(poTmp) )
81 if( NULL == json_object_get_object(poTmp)->head )
87 for( it.entry = json_object_get_object(poTmp)->head;
89 ( it.key = (
char*)it.entry->k,
90 it.val = (json_object*)it.entry->v, it.entry) : 0);
91 it.entry = it.entry->next)
93 if( strcasecmp((
char *)it.key, pszName )==0 )
107 LWDEBUGF(3,
"parse_geojson_coord called for object %s.", json_object_to_json_string( poObj ) );
109 if( json_type_array == json_object_get_type( poObj ) )
112 json_object* poObjCoord = NULL;
113 const int nSize = json_object_array_length( poObj );
114 LWDEBUGF(3,
"parse_geojson_coord called for array size %d.", nSize );
123 poObjCoord = json_object_array_get_idx( poObj, 0 );
124 pt.
x = json_object_get_double( poObjCoord );
125 LWDEBUGF(3,
"parse_geojson_coord pt.x = %f.", pt.
x );
128 poObjCoord = json_object_array_get_idx( poObj, 1 );
129 pt.
y = json_object_get_double( poObjCoord );
130 LWDEBUGF(3,
"parse_geojson_coord pt.y = %f.", pt.
y );
135 poObjCoord = json_object_array_get_idx( poObj, 2 );
136 pt.
z = json_object_get_double( poObjCoord );
137 LWDEBUGF(3,
"parse_geojson_coord pt.z = %f.", pt.
z );
140 else if ( nSize == 2 )
170 json_object* coords = NULL;
172 LWDEBUGF(3,
"parse_geojson_point called with root_srid = %d.", root_srid );
185 LWDEBUG(2,
"parse_geojson_point finished.");
194 json_object* points = NULL;
197 LWDEBUG(2,
"parse_geojson_linestring called.");
208 if( json_type_array == json_object_get_type( points ) )
210 const int nPoints = json_object_array_length( points );
211 for(i = 0; i < nPoints; ++i)
213 json_object* coords = NULL;
214 coords = json_object_array_get_idx( points, i );
221 LWDEBUG(2,
"parse_geojson_linestring finished.");
229 json_object* rings = NULL;
230 json_object* points = NULL;
232 int nRings = 0, nPoints = 0;
241 if ( json_type_array != json_object_get_type(rings) )
247 nRings = json_object_array_length( rings );
255 for ( i = 0; i < nRings; i++ )
257 points = json_object_array_get_idx(rings, i);
258 if ( ! points || json_object_get_type(points) != json_type_array )
260 geojson_lwerror(
"The 'coordinates' in GeoJSON ring are not an array", 4);
263 nPoints = json_object_array_length(points);
269 for ( j = 0; j < nPoints; j++ )
271 json_object* coords = NULL;
272 coords = json_object_array_get_idx( points, j );
276 for (k = 0; k <= i; k++)
281 geojson_lwerror(
"The 'coordinates' in GeoJSON polygon are not sufficiently nested", 4);
299 json_object* poObjPoints = NULL;
317 if( json_type_array == json_object_get_type( poObjPoints ) )
319 const int nPoints = json_object_array_length( poObjPoints );
320 for( i = 0; i < nPoints; ++i)
323 json_object* poObjCoords = NULL;
324 poObjCoords = json_object_array_get_idx( poObjPoints, i );
342 json_object* poObjLines = NULL;
360 if( json_type_array == json_object_get_type( poObjLines ) )
362 const int nLines = json_object_array_length( poObjLines );
363 for( i = 0; i < nLines; ++i)
366 json_object* poObjLine = NULL;
367 poObjLine = json_object_array_get_idx( poObjLines, i );
370 if( json_type_array == json_object_get_type( poObjLine ) )
372 const int nPoints = json_object_array_length( poObjLine );
373 for(j = 0; j < nPoints; ++j)
375 json_object* coords = NULL;
376 coords = json_object_array_get_idx( poObjLine, j );
394 json_object* poObjPolys = NULL;
412 if( json_type_array == json_object_get_type( poObjPolys ) )
414 const int nPolys = json_object_array_length( poObjPolys );
416 for(i = 0; i < nPolys; ++i)
418 json_object* poObjPoly = json_object_array_get_idx( poObjPolys, i );
420 if( json_type_array == json_object_get_type( poObjPoly ) )
423 int nRings = json_object_array_length( poObjPoly );
425 for(j = 0; j < nRings; ++j)
427 json_object* points = json_object_array_get_idx( poObjPoly, j );
429 if( json_type_array == json_object_get_type( points ) )
434 int nPoints = json_object_array_length( points );
435 for ( k=0; k < nPoints; k++ )
437 json_object* coords = json_object_array_get_idx( points, k );
457 json_object* poObjGeoms = NULL;
475 if( json_type_array == json_object_get_type( poObjGeoms ) )
477 const int nGeoms = json_object_array_length( poObjGeoms );
478 json_object* poObjGeom = NULL;
479 for(i = 0; i < nGeoms; ++i )
481 poObjGeom = json_object_array_get_idx( poObjGeoms, i );
493 json_object*
type = NULL;
496 if( NULL == geojson )
509 name = json_object_get_string( type );
511 if( strcasecmp( name,
"Point" )==0 )
514 if( strcasecmp( name,
"LineString" )==0 )
517 if( strcasecmp( name,
"Polygon" )==0 )
520 if( strcasecmp( name,
"MultiPoint" )==0 )
523 if( strcasecmp( name,
"MultiLineString" )==0 )
526 if( strcasecmp( name,
"MultiPolygon" )==0 )
529 if( strcasecmp( name,
"GeometryCollection" )==0 )
532 lwerror(
"invalid GeoJson representation");
543 lwerror(
"You need JSON-C for lwgeom_from_geojson");
551 json_tokener* jstok = NULL;
552 json_object* poObj = NULL;
553 json_object* poObjSrs = NULL;
557 jstok = json_tokener_new();
558 poObj = json_tokener_parse_ex(jstok, geojson, -1);
559 if( jstok->err != json_tokener_success)
563 json_tokener_free(jstok);
564 json_object_put(poObj);
568 json_tokener_free(jstok);
571 if (poObjSrs != NULL)
574 if (poObjSrsType != NULL)
582 const char* pszName = json_object_get_string( poNameURL );
585 *srs =
lwalloc(strlen(pszName) + 1);
586 strcpy(*srs, pszName);
594 json_object_put(poObj);
604 LWDEBUG(2,
"geom_from_geojson called.");
static LWGEOM * parse_geojson(json_object *geojson, int *hasz, int root_srid)
static void geojson_lwerror(char *msg, __attribute__((__unused__)) int error_code)
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
void lwgeom_free(LWGEOM *geom)
void ptarray_free(POINTARRAY *pa)
static LWGEOM * parse_geojson_multipolygon(json_object *geojson, int *hasz, int root_srid)
#define LWDEBUG(level, msg)
static int parse_geojson_coord(json_object *poObj, int *hasz, POINTARRAY *pa)
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
static LWGEOM * parse_geojson_polygon(json_object *geojson, int *hasz, int root_srid)
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE, then a duplicate point will not be added.
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
#define LW_TRUE
Return types for functions with status returns.
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
#define json_tokener_error_desc(x)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
static LWGEOM * parse_geojson_multilinestring(json_object *geojson, int *hasz, int root_srid)
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
static LWGEOM * parse_geojson_linestring(json_object *geojson, int *hasz, int root_srid)
static LWGEOM * parse_geojson_point(json_object *geojson, int *hasz, int root_srid)
static LWGEOM * parse_geojson_geometrycollection(json_object *geojson, int *hasz, int root_srid)
static json_object * findMemberByName(json_object *poObj, const char *pszName)
LWMPOINT * lwmpoint_add_lwpoint(LWMPOINT *mobj, const LWPOINT *obj)
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
#define FLAGS_GET_M(flags)
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
void * lwalloc(size_t size)
static LWGEOM * parse_geojson_multipoint(json_object *geojson, int *hasz, int root_srid)
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
#define LWDEBUGF(level, msg,...)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
This library is the generic geometry handling section of PostGIS.
LWGEOM * lwgeom_from_geojson(const char *geojson, char **srs)
Create an LWGEOM object from a GeoJSON representation.