static LWGEOM* parse_geojson_geometrycollection(json_object *geojson, bool *hasz, int *root_srid) { LWGEOM *geom = NULL; int i; json_object* poObjGeoms = NULL; if (!*root_srid) { geom = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, *root_srid, 1, 0); } else { geom = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, -1, 1, 0); } poObjGeoms = findMemberByName( geojson, "geometries" ); if ( ! poObjGeoms ) geojson_lwerror("Unable to find 'geometries' in GeoJSON string", 4); if( json_type_array == json_object_get_type( poObjGeoms ) ) { const int nGeoms = json_object_array_length( poObjGeoms ); json_object* poObjGeom = NULL; for(i = 0; i < nGeoms; ++i ) { poObjGeom = json_object_array_get_idx( poObjGeoms, i ); geom = (LWGEOM*)lwcollection_add_lwgeom((LWCOLLECTION *)geom, parse_geojson(poObjGeom, hasz, root_srid)); } } return geom; }
Datum geom_from_geojson(PG_FUNCTION_ARGS) { #ifndef HAVE_LIBJSON elog(ERROR, "You need JSON-C for ST_GeomFromGeoJSON"); PG_RETURN_NULL(); #else /* HAVE_LIBJSON */ GSERIALIZED *geom; LWGEOM *lwgeom; text *geojson_input; int geojson_size; char *geojson; int root_srid=0; bool hasz=true; json_tokener* jstok = NULL; json_object* poObj = NULL; json_object* poObjSrs = NULL; /* Get the geojson stream */ if (PG_ARGISNULL(0)) PG_RETURN_NULL(); geojson_input = PG_GETARG_TEXT_P(0); geojson = text2cstring(geojson_input); geojson_size = VARSIZE(geojson_input) - VARHDRSZ; /* Begin to Parse json */ jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, geojson, -1); if( jstok->err != json_tokener_success) { char err[256]; snprintf(err, 256, "%s (at offset %d)", json_tokener_errors[jstok->err], jstok->char_offset); json_tokener_free(jstok); geojson_lwerror(err, 1); } json_tokener_free(jstok); poObjSrs = findMemberByName( poObj, "crs" ); if (poObjSrs != NULL) { json_object* poObjSrsType = findMemberByName( poObjSrs, "type" ); if (poObjSrsType != NULL) { json_object* poObjSrsProps = findMemberByName( poObjSrs, "properties" ); json_object* poNameURL = findMemberByName( poObjSrsProps, "name" ); const char* pszName = json_object_get_string( poNameURL ); root_srid = getSRIDbySRS(pszName); POSTGIS_DEBUGF(3, "getSRIDbySRS returned root_srid = %d.", root_srid ); } } lwgeom = parse_geojson(poObj, &hasz, &root_srid); lwgeom_add_bbox(lwgeom); if (root_srid && lwgeom->srid == -1) lwgeom->srid = root_srid; if (!hasz) { LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; POSTGIS_DEBUG(2, "geom_from_geojson called."); } geom = geometry_serialize(lwgeom); lwgeom_free(lwgeom); PG_RETURN_POINTER(geom); #endif }
LWGEOM* lwgeom_from_geojson(const char *geojson, char **srs) { #ifndef HAVE_LIBJSON *srs = NULL; lwerror("You need JSON-C for lwgeom_from_geojson"); return NULL; #else /* HAVE_LIBJSON */ /* size_t geojson_size = strlen(geojson); */ LWGEOM *lwgeom; int hasz=LW_TRUE; json_tokener* jstok = NULL; json_object* poObj = NULL; json_object* poObjSrs = NULL; *srs = NULL; /* Begin to Parse json */ jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, geojson, -1); if( jstok->err != json_tokener_success) { char err[256]; snprintf(err, 256, "%s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); json_object_put(poObj); geojson_lwerror(err, 1); return NULL; } json_tokener_free(jstok); poObjSrs = findMemberByName( poObj, "crs" ); if (poObjSrs != NULL) { json_object* poObjSrsType = findMemberByName( poObjSrs, "type" ); if (poObjSrsType != NULL) { json_object* poObjSrsProps = findMemberByName( poObjSrs, "properties" ); if ( poObjSrsProps ) { json_object* poNameURL = findMemberByName( poObjSrsProps, "name" ); if ( poNameURL ) { const char* pszName = json_object_get_string( poNameURL ); if ( pszName ) { *srs = lwalloc(strlen(pszName) + 1); strcpy(*srs, pszName); } } } } } lwgeom = parse_geojson(poObj, &hasz, 0); json_object_put(poObj); lwgeom_add_bbox(lwgeom); if (!hasz) { LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; LWDEBUG(2, "geom_from_geojson called."); } return lwgeom; #endif /* HAVE_LIBJSON } */ }