Datum geography_as_binary(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; uint8_t *wkb = NULL; bytea *wkb_result; size_t wkb_size = 0; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* Get our lwgeom form */ lwgeom = lwgeom_from_gserialized(g); if ( gserialized_ndims(g) > 2 ) { /* Strip out the higher dimensions */ LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; } /* Create WKB */ wkb = lwgeom_to_wkb(lwgeom, WKB_SFSQL, &wkb_size); /* Copy to varlena pointer */ wkb_result = palloc(wkb_size + VARHDRSZ); SET_VARSIZE(wkb_result, wkb_size + VARHDRSZ); memcpy(VARDATA(wkb_result), wkb, wkb_size); /* Clean up */ pfree(wkb); lwgeom_free(lwgeom); PG_RETURN_BYTEA_P(wkb_result); }
static void test_misc_force_2d(void) { LWGEOM *geom; LWGEOM *geom2d; char *wkt_out; geom = lwgeom_from_wkt("CIRCULARSTRINGM(-5 0 4,0 5 3,5 0 2,10 -5 1,15 0 0)", LW_PARSER_CHECK_NONE); geom2d = lwgeom_force_2d(geom); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); geom = lwgeom_from_wkt("GEOMETRYCOLLECTION(POINT(0 0 0),LINESTRING(1 1 1,2 2 2),POLYGON((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),CURVEPOLYGON(CIRCULARSTRING(0 0 0,1 1 1,2 2 2,1 1 1,0 0 0)))", LW_PARSER_CHECK_NONE); geom2d = lwgeom_force_2d(geom); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2),POLYGON((0 0,0 1,1 1,1 0,0 0)),CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 2,1 1,0 0)))",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); }
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 }
Datum geom_from_kml(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom, *hlwgeom; xmlDocPtr xmldoc; text *xml_input; int xml_size; char *xml; bool hasz=true; xmlNodePtr xmlroot=NULL; /* Get the KML stream */ if (PG_ARGISNULL(0)) PG_RETURN_NULL(); xml_input = PG_GETARG_TEXT_P(0); xml = text2cstring(xml_input); xml_size = VARSIZE(xml_input) - VARHDRSZ; /* Begin to Parse XML doc */ xmlInitParser(); xmldoc = xmlParseMemory(xml, xml_size); if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL) { xmlFreeDoc(xmldoc); xmlCleanupParser(); lwerror("invalid KML representation"); } lwgeom = parse_kml(xmlroot, &hasz); /* Homogenize geometry result if needed */ if (lwgeom->type == COLLECTIONTYPE) { hlwgeom = lwgeom_homogenize(lwgeom); lwgeom_release(lwgeom); lwgeom = hlwgeom; } lwgeom_add_bbox(lwgeom); /* KML geometries could be either 2 or 3D * * So we deal with 3D in all structures allocation, and flag hasz * to false if we met once a missing Z dimension * In this case, we force recursive 2D. */ if (!hasz) { LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; } geom = geometry_serialize(lwgeom); lwgeom_free(lwgeom); xmlFreeDoc(xmldoc); xmlCleanupParser(); PG_RETURN_POINTER(geom); }
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 } */ }