Top 5 Recent Articles
ARTICLES CATEGORIES
- Algorithms (22)
- All (399)
- Biography (1)
- Blog (44)
- Business Requirements (1)
- Commentary (1)
- Conversion (2)
- Customers (2)
- Data Models (1)
- Education (2)
- GeoRaptor (13)
- GPS (1)
- Image Processing (2)
- Import Export (8)
- Licensing (2)
- LiDAR (1)
- Linear Referencing (4)
- Manifold GIS (3)
- Mapping (1)
- MySQL Spatial (7)
- Networking and Routing (including Optimization) (5)
- Open Source (18)
- Oracle Spatial and Locator (194)
- Partitioning (1)
- PostGIS (36)
- Projections (1)
- Published Articles (1)
- qGIS (1)
- Recommendations (1)
- Services (1)
- Software Change Log (1)
- Source Code (37)
- Space Curves (9)
- Spatial Database Functions (109)
- Spatial DB comparison (1)
- Spatial XML Processing (11)
- SQL Server Spatial (92)
- Standards (3)
- Stored Procedure (17)
- Tessellation or Gridding (10)
- Tools (2)
- Topological Relationships (1)
- Training (2)
- Triangulation (2)
Convert GeoJSON document to Sdo_Geometry objects
Andy Versal is a reader of this website.
He recently modified my SDO2GEOJSON function.
Andy supplied me with the fixes which now appear in the original article describing that function.
In return he has provided me with a copy of his function that converts GeoJSON to Sdo_Geometry.
CREATE OR REPLACE FUNCTION geoJSON2SDO(p_geoJson IN CLOB, p_sdo_srid IN NUMBER DEFAULT 8307, p_decimal_places IN pls_integer DEFAULT 7, p_num_fmt IN varchar2 DEFAULT '999.99999999999999999999') RETURN sdo_geometry IS -- Supports only geometry.type : polygon, multipolygon with or without holes -- Oracle RDBMS 12c only l_geometry sdo_geometry; l_poly_ord sdo_ordinate_array := sdo_ordinate_array(); l_info_array sdo_elem_info_array := sdo_elem_info_array(); i pls_integer:=0; l_gtype varchar2(50); l_sdo_gtype NUMBER:=NULL; l_ring_num pls_integer:=0; l_poly_count pls_integer:=0; l_geom_errors varchar2(4000); l_ord_offset pls_integer:=0; BEGIN SELECT json_value(p_geoJson,'$.geometry.type') INTO l_gtype FROM dual; -- polygon IF LOWER(l_gtype)='polygon' THEN -- Geometry contains one polygon with or without holes l_sdo_gtype:=2003; -- ordinates SELECT trunc(to_number(ord,p_num_fmt),p_decimal_places) bulk collect INTO l_poly_ord FROM json_table(p_geoJson,'$.geometry.coordinates[*]' COLUMNS (nested path '$[*]' COLUMNS (nested path '$[*]' COLUMNS (ord VARCHAR2(100) path '$') ) ) ) WHERE ord IS NOT NULL; IF l_poly_ord.COUNT!=0 THEN -- rings loop, sdo_elem_info FOR r IN (SELECT num1,num2,trunc(to_number(ord,p_num_fmt),p_decimal_places) FROM json_table(p_geoJson,'$.geometry.coordinates[*]' COLUMNS (num1 FOR ORDINALITY,nested path '$[*]' COLUMNS (num2 FOR ORDINALITY, nested path '$[*]' COLUMNS (ord VARCHAR2(100) path '$') ) ) ) WHERE ord IS NOT NULL AND num2=1) loop i:=i+1;l_ring_num:=l_ring_num+1; l_info_array.extend; l_info_array(i):=r.num1; i:=i+1; l_info_array.extend; IF l_ring_num=1 THEN -- exterior polygon ring l_info_array(i):=1003; ELSE -- interior polygon ring l_info_array(i):=2003; END IF; i:=i+1; l_info_array.extend; l_info_array(i):=1; END loop; END IF; END IF; -- multipolygon IF LOWER(l_gtype)='multipolygon' THEN -- Geometry can have multiple, disjoint polygons (more than one exterior boundary) l_sdo_gtype:=2007; -- ordinates SELECT trunc(to_number(ord,p_num_fmt),p_decimal_places) bulk collect INTO l_poly_ord FROM json_table(p_geoJson,'$.geometry.coordinates[*]' COLUMNS (nested path '$[*]' COLUMNS (nested path '$[*]' COLUMNS (nested path '$[*]' COLUMNS (ord VARCHAR2(100) path '$') ) ) ) ) WHERE ord IS NOT NULL; IF l_poly_ord.COUNT!=0 THEN -- polygons loop FOR p IN (SELECT * FROM json_table( p_geoJson,'$.geometry.coordinates[*]' COLUMNS (polyords varchar2(4000) FORMAT JSON path '$') ) ) loop l_poly_count:=l_poly_count+1; -- rings loop, sdo_elem_info l_ring_num:=0; FOR r IN (SELECT num1,num2,trunc(to_number(ord,p_num_fmt),p_decimal_places) FROM json_table(p.polyords,'$[*]' COLUMNS (num1 FOR ORDINALITY,nested path '$[*]' COLUMNS (num2 FOR ORDINALITY, nested path '$[*]' COLUMNS (ord VARCHAR2(100) path '$') ) ) ) WHERE ord IS NOT NULL AND num2=1) loop i:=i+1;l_ring_num:=l_ring_num+1; l_info_array.extend; l_info_array(i):=r.num1+l_ord_offset; i:=i+1; l_info_array.extend; IF l_ring_num=1 THEN -- exterior polygon ring l_info_array(i):=1003; ELSE -- interior polygon ring l_info_array(i):=2003; END IF; i:=i+1; l_info_array.extend; l_info_array(i):=1; END loop; -- ordinates offset SELECT COUNT(*)+l_ord_offset INTO l_ord_offset FROM json_table(p.polyords,'$[*]' COLUMNS (nested path '$[*]' COLUMNS (nested path '$[*]' COLUMNS (ord VARCHAR2(100) path '$') ) ) ) WHERE ord IS NOT NULL; END loop; IF l_poly_count=1 THEN l_sdo_gtype:=2003; END IF; END IF; END IF; IF l_sdo_gtype IS NOT NULL THEN IF l_poly_ord.COUNT=0 THEN RETURN NULL; ELSE l_geometry:=sdo_geometry(l_sdo_gtype,p_sdo_srid,NULL,l_info_array,l_poly_ord); -- check geometry SELECT sdo_geom.validate_geometry_with_context(l_geometry,diminfo) INTO l_geom_errors FROM user_sdo_geom_metadata; IF l_geom_errors!='TRUE' THEN -- fix ora-13367 error (wrong orientation for interior/exterior rings) IF l_geom_errors LIKE '13367 %' THEN l_geometry:=sdo_util.rectify_geometry(l_geometry,0.005); ELSE raise_application_error(-20000,l_geom_errors); END IF; END IF; RETURN l_geometry; END IF; END IF; END geoJSON2SDO;
Thanks to Andy Versal for this function.
Documentation
- MySQL Spatial General Functions
- Oracle LRS Objects
- Oracle Spatial Exporter (Java + pl/SQL)
- Oracle Spatial Object Functions
- Oracle Spatial Object Functions (Multi Page)
- PostGIS pl/pgSQL Functions
- SC4O Oracle Java Topology Suite (Java + pl/SQL)
- SQL Server Spatial General TSQL Functions
- SQL Server Spatial LRS TSQL Functions