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);
118 lwerror(
"Too few ordinates in GeoJSON");
123 poObjCoord = json_object_array_get_idx(poObj, 0);
124 pt.
x = json_object_get_double(poObjCoord);
127 poObjCoord = json_object_array_get_idx(poObj, 1);
128 pt.
y = json_object_get_double(poObjCoord);
133 poObjCoord = json_object_array_get_idx(poObj, 2);
134 pt.
z = json_object_get_double(poObjCoord);
141 lwerror(
"The 'coordinates' in GeoJSON are not sufficiently nested");
166 const int nPoints = json_object_array_length(points);
167 for (
int i = 0; i < nPoints; i++)
169 json_object *coords = json_object_array_get_idx(points, i);
178 if (!rings || json_object_get_type(rings) != json_type_array)
181 int nRings = json_object_array_length(rings);
191 for (
int i = 0; i < nRings; i++)
193 json_object *points = json_object_array_get_idx(rings, i);
194 if (!points || json_object_get_type(points) != json_type_array)
196 for (
int k = 0; k < o; k++)
199 lwerror(
"The 'coordinates' in GeoJSON ring are not an array");
202 int nPoints = json_object_array_length(points);
215 for (
int j = 0; j < nPoints; j++)
217 json_object *coords = NULL;
218 coords = json_object_array_get_idx(points, j);
221 for (
int k = 0; k <= o; k++)
224 lwerror(
"The 'coordinates' in GeoJSON are not sufficiently nested");
255 const int nPoints = json_object_array_length(points);
256 for (
int i = 0; i < nPoints; ++i)
259 json_object *coord = json_object_array_get_idx(points, i);
280 const int nLines = json_object_array_length(mls);
281 for (
int i = 0; i < nLines; ++i)
284 json_object *coords = json_object_array_get_idx(mls, i);
286 if (json_type_array == json_object_get_type(coords))
288 const int nPoints = json_object_array_length(coords);
289 for (
int j = 0; j < nPoints; ++j)
291 json_object *coord = json_object_array_get_idx(coords, j);
318 int nPolys = json_object_array_length(polys);
320 for (
int i = 0; i < nPolys; ++i)
322 json_object *rings = json_object_array_get_idx(polys, i);
337 lwerror(
"Unable to find 'geometries' in GeoJSON string");
342 if (json_type_array == json_object_get_type(poObjGeoms))
344 const int nGeoms = json_object_array_length(poObjGeoms);
345 for (
int i = 0; i < nGeoms; ++i)
347 json_object *poObjGeom = json_object_array_get_idx(poObjGeoms, i);
365 json_object *
type = NULL;
370 lwerror(
"invalid GeoJSON representation");
377 lwerror(
"unknown GeoJSON type");
381 name = json_object_get_string(
type);
383 if (strcasecmp(name,
"Point") == 0)
386 if (strcasecmp(name,
"LineString") == 0)
389 if (strcasecmp(name,
"Polygon") == 0)
392 if (strcasecmp(name,
"MultiPoint") == 0)
395 if (strcasecmp(name,
"MultiLineString") == 0)
398 if (strcasecmp(name,
"MultiPolygon") == 0)
401 if (strcasecmp(name,
"GeometryCollection") == 0)
404 lwerror(
"invalid GeoJson representation");
415 lwerror(
"You need JSON-C for lwgeom_from_geojson");
420 json_tokener *jstok = json_tokener_new();
421 json_object *poObj = json_tokener_parse_ex(jstok, geojson, -1);
422 if (jstok->err != json_tokener_success)
426 json_tokener_free(jstok);
427 json_object_put(poObj);
431 json_tokener_free(jstok);
435 if (poObjSrs != NULL)
438 if (poObjSrsType != NULL)
446 const char *pszName = json_object_get_string(poNameURL);
449 *srs =
lwalloc(strlen(pszName) + 1);
450 strcpy(*srs, pszName);
459 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)