29 #include "../postgis_config.h"
31 #if defined(HAVE_LIBJSON)
33 #define JSON_C_VERSION_013 (13 << 8)
37 #if !defined(JSON_C_VERSION_NUM) || JSON_C_VERSION_NUM < JSON_C_VERSION_013
38 #include <json_object_private.h>
41 #ifndef JSON_C_VERSION
43 #define json_tokener_error_desc(x) json_tokener_errors[(x)]
51 static inline json_object *
59 if (!pszName || !poObj)
66 if (json_object_get_object(poTmp))
68 if (!json_object_get_object(poTmp)->head)
70 lwerror(
"invalid GeoJSON representation");
74 for (it.entry = json_object_get_object(poTmp)->head;
75 (it.entry ? (it.key = (
char *)it.entry->k, it.val = (json_object *)it.entry->v, it.entry) : 0);
76 it.entry = it.entry->next)
78 if (strcasecmp((
char *)it.key, pszName) == 0)
86 static inline json_object *
92 lwerror(
"Unable to find 'coordinates' in GeoJSON string");
96 if (json_type_array != json_object_get_type(coordinates))
98 lwerror(
"The 'coordinates' in GeoJSON are not an array");
110 if (json_object_get_type(poObj) == json_type_array)
112 json_object *poObjCoord = NULL;
113 const int nSize = json_object_array_length(poObj);
116 lwerror(
"Too few ordinates in GeoJSON");
121 poObjCoord = json_object_array_get_idx(poObj, 0);
122 pt.
x = json_object_get_double(poObjCoord);
125 poObjCoord = json_object_array_get_idx(poObj, 1);
126 pt.
y = json_object_get_double(poObjCoord);
131 poObjCoord = json_object_array_get_idx(poObj, 2);
132 pt.
z = json_object_get_double(poObjCoord);
139 lwerror(
"The 'coordinates' in GeoJSON are not sufficiently nested");
164 const int nPoints = json_object_array_length(points);
165 for (
int i = 0; i < nPoints; i++)
167 json_object *coords = json_object_array_get_idx(points, i);
176 if (!rings || json_object_get_type(rings) != json_type_array)
179 int nRings = json_object_array_length(rings);
189 for (
int i = 0; i < nRings; i++)
191 json_object *points = json_object_array_get_idx(rings, i);
192 if (!points || json_object_get_type(points) != json_type_array)
194 for (
int k = 0; k < o; k++)
197 lwerror(
"The 'coordinates' in GeoJSON ring are not an array");
200 int nPoints = json_object_array_length(points);
213 for (
int j = 0; j < nPoints; j++)
215 json_object *coords = NULL;
216 coords = json_object_array_get_idx(points, j);
219 for (
int k = 0; k <= o; k++)
222 lwerror(
"The 'coordinates' in GeoJSON are not sufficiently nested");
253 const int nPoints = json_object_array_length(points);
254 for (
int i = 0; i < nPoints; ++i)
257 json_object *coord = json_object_array_get_idx(points, i);
278 const int nLines = json_object_array_length(mls);
279 for (
int i = 0; i < nLines; ++i)
282 json_object *coords = json_object_array_get_idx(mls, i);
284 if (json_type_array == json_object_get_type(coords))
286 const int nPoints = json_object_array_length(coords);
287 for (
int j = 0; j < nPoints; ++j)
289 json_object *coord = json_object_array_get_idx(coords, j);
316 int nPolys = json_object_array_length(polys);
318 for (
int i = 0; i < nPolys; ++i)
320 json_object *rings = json_object_array_get_idx(polys, i);
335 lwerror(
"Unable to find 'geometries' in GeoJSON string");
340 if (json_type_array == json_object_get_type(poObjGeoms))
342 const int nGeoms = json_object_array_length(poObjGeoms);
343 for (
int i = 0; i < nGeoms; ++i)
345 json_object *poObjGeom = json_object_array_get_idx(poObjGeoms, i);
363 json_object *
type = NULL;
368 lwerror(
"invalid GeoJSON representation");
375 lwerror(
"unknown GeoJSON type");
379 name = json_object_get_string(
type);
381 if (strcasecmp(name,
"Point") == 0)
384 if (strcasecmp(name,
"LineString") == 0)
387 if (strcasecmp(name,
"Polygon") == 0)
390 if (strcasecmp(name,
"MultiPoint") == 0)
393 if (strcasecmp(name,
"MultiLineString") == 0)
396 if (strcasecmp(name,
"MultiPolygon") == 0)
399 if (strcasecmp(name,
"GeometryCollection") == 0)
402 lwerror(
"invalid GeoJson representation");
413 lwerror(
"You need JSON-C for lwgeom_from_geojson");
418 json_tokener *jstok = json_tokener_new();
419 json_object *poObj = json_tokener_parse_ex(jstok, geojson, -1);
420 if (jstok->err != json_tokener_success)
424 json_tokener_free(jstok);
425 json_object_put(poObj);
429 json_tokener_free(jstok);
433 if (poObjSrs != NULL)
436 if (poObjSrsType != NULL)
444 const char *pszName = json_object_get_string(poNameURL);
447 *srs =
lwalloc(strlen(pszName) + 1);
448 strcpy(*srs, pszName);
457 json_object_put(poObj);
void lwmpoint_free(LWMPOINT *mpt)
void lwgeom_free(LWGEOM *geom)
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWMPOINT * lwmpoint_add_lwpoint(LWMPOINT *mobj, const LWPOINT *obj)
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
void ptarray_free(POINTARRAY *pa)
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,...
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
void lwmline_free(LWMLINE *mline)
#define LW_TRUE
Return types for functions with status returns.
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
This library is the generic geometry handling section of PostGIS.
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
LWGEOM * lwgeom_from_geojson(const char *geojson, char **srs)
Create an LWGEOM object from a GeoJSON representation.
static LWGEOM * parse_geojson_geometrycollection(json_object *geojson, int *hasz)
#define json_tokener_error_desc(x)
static LWGEOM * parse_geojson(json_object *geojson, int *hasz)
static json_object * parse_coordinates(json_object *geojson)
static LWGEOM * parse_geojson_multipoint(json_object *geojson, int *hasz)
static LWGEOM * parse_geojson_multipolygon(json_object *geojson, int *hasz)
static LWGEOM * parse_geojson_multilinestring(json_object *geojson, int *hasz)
static int parse_geojson_coord(json_object *poObj, int *hasz, POINTARRAY *pa)
static LWPOLY * parse_geojson_poly_rings(json_object *rings, int *hasz)
static LWGEOM * parse_geojson_linestring(json_object *geojson, int *hasz)
static LWGEOM * parse_geojson_polygon(json_object *geojson, int *hasz)
static LWGEOM * parse_geojson_point(json_object *geojson, int *hasz)
static json_object * findMemberByName(json_object *poObj, const char *pszName)