diff --git a/1911.pdf b/1911.pdf new file mode 100644 index 0000000..331946a Binary files /dev/null and b/1911.pdf differ diff --git a/1930.html b/1930.html new file mode 100644 index 0000000..cf2d708 --- /dev/null +++ b/1930.html @@ -0,0 +1,25 @@ +PART 1 – Overview
+Chapter 1 – Spatial Information Management
+Chapter 2 – Overview of Oracle Spatial
+Chapter 3 – Location-Enabling Your Applications
+
+PART 2 – Basic Spatial
+Chapter 4 – The SDO_GEOMETRY Data Type
+Chapter 5 – Loading, Transporting, and Validating Spatial Data
+Chapter 6 – Geocoding
+Chapter 7 – Manipulating SDO_GEOMETRY in Application Programs
+
+PART 3 – Analysis and Visualization
+Chapter 8 – Spatial Indexes and Operators
+Chapter 9 – Geometry Processing Functions
+Chapter 10 – Network Modeling
+Chapter 11 – Generating Maps Using MapViewer
+Chapter 12 – A Sample Application
+
+PART 4 – Advanced Spatial
+Chapter 13 – Case Studies
+Chapter 14 – Tips, Common Mistakes, and Common Errors
+Appendix A – Additional Spatial Analysis Functions
+Appendix B – Linear Referencing
+Appendix C – Topology Data Model in Oracle
+Appendix D – Storing Raster Data in Oracle \ No newline at end of file diff --git a/2443.html b/2443.html new file mode 100644 index 0000000..a99d428 --- /dev/null +++ b/2443.html @@ -0,0 +1 @@ + Errata for 582-3 Asleson (corrected in the second printing)

Errata 383-9 Kothuri (corrected in the 2nd printing)

Page

Original Sentence

Corrected Sentence

24

For instance, the center of San Francisco is located at

coordinates (–122.436, –37.719) in the two-dimensional Ňlatitude, longitudeÓ space.

For instance, the center of San Francisco is located at

coordinates (–122.436, 37.719) in the two-dimensional Ňlatitude, longitudeÓ space.

25

For example, you can insert a location of (–87, –78) for a Pizza Hut restaurant into the us_restaurants table as shown in Listing 2-2.

For example, you can insert a location of (–87, 38) for a Pizza Hut restaurant into the us_restaurants table as shown in Listing 2-2.

25

-78, -- second ordinate, i.e., value in latitude dimension

38, -- second ordinate, i.e., value in latitude dimension

49

landsqmia                NUMBER,

landsqmi                 NUMBER,

68

SQL> SELECT a.location.sdo_gtype FROM us_states a WHERE state_abrv='NH';

SQL> SELECT a.geom.sdo_gtype FROM us_states a WHERE state_abrv='NH';

68

SQL> SELECT a.location.sdo_gtype FROM us_cities a WHERE state_abrv='TX';

SQL> SELECT a.geom.sdo_gtype FROM us_cities a WHERE state_abrv='TX';

106

FIELDS TERMINATED BY '|'

TRAILING NULLCOLS

INTO TABLE sales_regions

APPEND

FIELDS TERMINATED BY '|'

107

INTO TABLE sales_regions

FIELDS TERMINATED BY '|'

INTO TABLE sales_regions

APPEND

FIELDS TERMINATED BY '|'

109

IMP scott/tiger FILE=customers.dmp IGNORE=Y INDEXES=N

IMP scott/tiger FILE=customers.dmp IGNORE=Y INDEXES=N TABLES=CUSTOMERS

110

EXP USERID = "'SYSTEM/MANAGER AS SYSDBA'" TRANSPORT_TABLESPACE=Y TABLESPACES=TBS

EXP USERID = "'SYS/<password>'" TRANSPORT_TABLESPACE=Y TABLESPACES=TBS

110

IMP USERID = "'SYSTEM/MANAGER AS SYSDBA'" TRANSPORT_TABLESPACE=Y FILE=trans_ts.dmp

IMP USERID = "'SYS/<password>'" TRANSPORT_TABLESPACE=Y FILE=trans_ts.dmp

111

SQLPLUS SYSTEM/MANAGER AS SYSDBA

SQLPLUS SYS/<password>

112

CREATE TABLE customers

DROP TABLE customers;

CREATE TABLE customers

114

xmltype(sdo_gml.to_gmlgeometry(geom)) as

xmltype(sdo_util.to_gmlgeometry(geom)) as

117

)

0.000005

)

),

0.000005

121

SDO_UTIL.REMOVE_DUPLICATE_VERTICES(a.geom, 0.5)

SDO_UTIL.REMOVE_DUPLICATE_VERTICES(a.geom, 0.5),

123

)

0.00005 -- tolerance

),

0.00005 -- tolerance

158

SQL> SET SERVEROUTPUT ON

SQL> SET SERVEROUTPUT ON SIZE 32000

161

SQL> SET SERVEROUTPUT ON

SQL> SET SERVEROUTPUT ON SIZE 10000

163

SQL> ALTER TABLE competitors ADD (location SDO_GEOMETRY)

SQL> ALTER TABLE competitors ADD (location SDO_GEOMETRY);

187

DETERMINISTIC

RETURN SDO_GEOMETRY

RETURN SDO_GEOMETRY

DETERMINISTIC

195

END

/

END;

/

230

SQL> DESCRIBE USER_SDO_GEOM_METDATA;

SQL> DESCRIBE USER_SDO_GEOM_METADATA;

269

SELECT ct.id, ct.name, SDO_NN_DISTANCE(1) dist

SELECT ct.id, ct.customer_grade, SDO_NN_DISTANCE(1) dist

275

Listing 8-53. Setting Session Parameters to Enable Query Rewrite on Function-Based Indexes

Listing 8-53. Setting Session Parameters to Enable Query Rewrite on Function-Based Indexes

(Not Necessary in Oracle 10g)

302

DECLARE

Geom mdsys.sdo_geometry

coverage mdsys.sdo_geometry := null;

BEGIN

OPEN cur FOR SELECT geom FROM sales_regions;

LOOP

EXIT WHEN cur%NOTFOUND;

FETCH cur INTO geom;

coverage := SDO_GEOM.SDO_UNION(coverage, geom);

END LOOP;

EXECUTE IMMEDIATE 'INSERT INTO sales_region_coverage values (:1)'

USING coverage;

COMMIT;

END;

 

CREATE TABLE sales_region_coverage (coverage SDO_GEOMETRY);

DECLARE

coverage SDO_GEOMETRY := NULL;

BEGIN

FOR g IN (SELECT geom FROM sales_regions) LOOP

coverage := SDO_GEOM.SDO_UNION(coverage, g.geom, 0.5);

END LOOP;

INSERT INTO sales_region_coverage values (coverage);

COMMIT;

END;

/

 

304

(SDO_GEOM.SDO_DIFFERENCE(csr.geom, sr.geom, 0.5)),

SDO_GEOM.SDO_DIFFERENCE(csr.geom, sr.geom, 0.5),

307

Listing 9-20. Area of the Intersection Region of Sales Region 1 and Sales Region 2

Listing 9-20. Area of the Intersection Region of Sales Region 43 and Sales Region 51

316

Listing 9-28. Finding the Coverage of sales_regions Using SDO_AGGR_UNION

Listing 9-28. Finding the Coverage of Branch Locations Using SDO_AGGR_UNION

343

SQL> EXEC show_net_details ('US_ROADS');

SET SERVEROUTPUT ON

SQL> EXEC show_net_details ('US_ROADS');

483

(None—text was inserted at bottom of page)

The sample application uses the network data model Java API. The initial loading of the network needs a database connection: this connection uses a native OC4J data source. This data source must be defined in the configuration file $OC4J_HOME/j2ee/home/config/data-sources.xml

Add the following OC4J data source definition in the configuration file:

<data-source

class="com.evermind.sql.DriverManagerDataSource"

name="spatial10g"

location="jdbc/spatial10gCore"

xa-location="jdbc/xa/spatial10gXA"

ejb-location="jdbc/spatial10g"

connection-driver="oracle.jdbc.driver.OracleDriver"

username="spatial"

password="spatial"

url="jdbc:oracle:thin:@localhost:1521:orcl101"

inactivity-timeout="30"

/>

Do not forget to adapt the database connection parameters to match your own setup. You can also define the MapViewer datasource based on this OC4J datasource. Read about this possibility on page 399 in Chapter 11.

 

581

WHERE b.table_name = 'CUSTOMERS' and b.column_name='LOCATION'

(None-line was deleted)

587

(None-text was inserted directly above Listing 14-15)

INSERT INTO USER_SDO_GEOM_METADATA VALUES

('WEATHER_PATTERNS', 'GEOM',

SDO_DIM_ARRAY(

SDO_DIM_ELEMENT('LONG', -180, 180, 0.5),

SDO_DIM_ELEMENT('LAT', -90, 90, 0.5)

),

8307

);

642

SQL> UPDATE branches SET georaster = SDO_GEOR.INIT('BRANCHES_RDT'); WHERE id=1

SQL> UPDATE branches SET georaster = SDO_GEOR.INIT('BRANCHES_RDT') WHERE id=1;

649

</theme>

</theme>

COMMIT;

 

\ No newline at end of file diff --git a/9781590593837.jpg b/9781590593837.jpg new file mode 100644 index 0000000..abf7195 Binary files /dev/null and b/9781590593837.jpg differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b9e31b9 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2004 Ravikanth Kothuri, Euro Beinat, and Albert Godfrind + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-01.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-01.sql new file mode 100644 index 0000000..a68d72b --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-01.sql @@ -0,0 +1,3 @@ +-- Listing A-1. Tiling a Two-Dimensional Space +SELECT * + FROM TABLE (SDO_SAM.TILED_BINS(-77.1027, -76.943996, 38.820813, 38.95911,1, 8307)); diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-02.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-02.sql new file mode 100644 index 0000000..b32fee1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-02.sql @@ -0,0 +1,2 @@ +-- Listing A-2. Zip Code Table Used to Get Demographic Information +desc zip5_dc; diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-03.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-03.sql new file mode 100644 index 0000000..98417f3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-03.sql @@ -0,0 +1,8 @@ +-- Listing A-3. Searching for Regions (Tiles) That Have a Population Greater Than 30,000 +SELECT REGION_ID, AGGREGATE_VALUE, GEOMETRY +FROM TABLE + ( + SDO_SAM.TILED_AGGREGATES + ('ZIP5_DC', 'GEOM','SUM', 'POPULATION', 2) + ) +WHERE aggregate_value > 30000; diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-04.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-04.sql new file mode 100644 index 0000000..e6e49f1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-04.sql @@ -0,0 +1,4 @@ +-- Listing A-4. Estimating the Population in Sales Region 1 Using the Demographic Information in the zip5_dc Table +SELECT SDO_SAM.AGGREGATES_FOR_GEOMETRY ('ZIP5_DC', 'GEOM', 'SUM', 'POPULATION', geom) population +FROM sales_regions +WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-05.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-05.sql new file mode 100644 index 0000000..a2e3180 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-05.sql @@ -0,0 +1,9 @@ +-- Listing A-5. Estimating the Population for All Rows in the sales_regions Table Using Demographic Information in the zip5_dc Table +SELECT b.id, aggregate_value population +FROM TABLE + ( + SDO_SAM.AGGREGATES_FOR_LAYER + ('ZIP5_DC', 'GEOM','SUM', 'POPULATION', 'SALES_REGIONS', 'GEOM') + ) a, + sales_regions b +WHERE b.rowid = a.region_id; diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-06.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-06.sql new file mode 100644 index 0000000..49324e8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-06.sql @@ -0,0 +1,3 @@ +-- Listing A-6. Finding Three Clusters for Customer Locations +SELECT ID, GEOMETRY +FROM TABLE (SDO_SAM.SPATIAL_CLUSTERS('CUSTOMERS', 'LOCATION', 3)); diff --git a/ProOracleSpatialCode/Code/Appendix-A/listing-A-07.sql b/ProOracleSpatialCode/Code/Appendix-A/listing-A-07.sql new file mode 100644 index 0000000..a6047b6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-A/listing-A-07.sql @@ -0,0 +1,4 @@ +-- Listing A-7. Simplifying the Geometry for New Hampshire +SELECT SDO_SAM.SIMPLIFY_GEOMETRY(geom, 0.5) +FROM us_states +WHERE state_abrv='NH'; diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-01.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-01.sql new file mode 100644 index 0000000..399eef9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-01.sql @@ -0,0 +1,2 @@ +-- Listing D-1. Altering the branches Table to Add the georaster Column +ALTER TABLE branches ADD ( georaster SDO_GEORASTER); diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-02.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-02.sql new file mode 100644 index 0000000..aab665f --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-02.sql @@ -0,0 +1,2 @@ +-- Listing D-2. Structure of SDO_GEORASTER +DESC SDO_GEORASTER; diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-03.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-03.sql new file mode 100644 index 0000000..22cc89a --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-03.sql @@ -0,0 +1,10 @@ +-- Listing D-3. Creating the Raster Data Table +CREATE TABLE branches_rdt OF SDO_RASTER +( + PRIMARY KEY + ( + RASTERID, PYRAMIDLEVEL, BANDBLOCKNUMBER, + ROWBLOCKNUMBER, COLUMNBLOCKNUMBER + ) +) +LOB(RASTERBLOCK) STORE AS (NOCACHE NOLOGGING); diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-04.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-04.sql new file mode 100644 index 0000000..01b799a --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-04.sql @@ -0,0 +1,2 @@ +-- Listing D-4. Creating a Trigger to Populate the Raster Data Table +call SDO_GEOR_UTL.createDMLTrigger('BRANCHES','GEORASTER'); diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-05.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-05.sql new file mode 100644 index 0000000..84c6cac --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-05.sql @@ -0,0 +1,4 @@ +-- Listing D-5. Initializing the georaster Column in the branches Table +UPDATE branches + SET georaster = SDO_GEOR.INIT('BRANCHES_RDT') + WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-06.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-06.sql new file mode 100644 index 0000000..2332292 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-06.sql @@ -0,0 +1,16 @@ +-- Listing D-6. Populating the Georaster Column with a TIFF Image +DECLARE + g SDO_GEORASTER; +BEGIN + -- Select the georaster column + SELECT georaster INTO g FROM branches WHERE id = 1 FOR UPDATE; + -- Import into the georaster object + SDO_GEOR.IMPORTFROM + ( + g, 'blocksize=(512,512)', 'TIFF', 'file', + '/usr/rasters/r1.tif' -- specify the name and location of the image file + ); + -- update the column + UPDATE branches SET georaster = g WHERE id = 1; +END; +/ diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-07.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-07.sql new file mode 100644 index 0000000..a9a0238 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-07.sql @@ -0,0 +1,18 @@ +-- Listing D-7. Granting Permissions to Import Data into a GeoRaster Column +CONNECT system/manager -- Replace with password for system + +-- Grant permission to user 'spatial' +CALL DBMS_JAVA.GRANT_PERMISSION( + 'SPATIAL', + 'SYS:java.io.FilePermission', + '/usr/rasters/r1.tif', + 'read'); + +-- Grant permission to the MDSYS schema +CALL DBMS_JAVA.GRANT_PERMISSION( + 'MDSYS', + 'SYS:java.io.FilePermission', + '/usr/rasters/r1.tif', + 'read'); + +CONNECT spatial/spatial diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-08.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-08.sql new file mode 100644 index 0000000..2688fb5 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-08.sql @@ -0,0 +1,10 @@ +-- Listing D-8. Generating Pyramids for a GeoRaster Object in the branches Table +DECLARE + geor sdo_georaster; +BEGIN + SELECT georaster INTO geor FROM branches WHERE id = 1 FOR UPDATE; + -- Generate four levels of pyramids + SDO_GEOR.GENERATEPYRAMID(geor, 'rlevel=4'); + UPDATE branches SET georaster = geor WHERE id = 1; +END; +/ diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-09.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-09.sql new file mode 100644 index 0000000..eaae842 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-09.sql @@ -0,0 +1,17 @@ +-- Listing D-9. Subsetting a GeoRaster Object +DECLARE + g SDO_GEORASTER; + b BLOB; +BEGIN + SELECT georaster INTO g FROM branches WHERE id = 1; + DBMS_LOB.CREATETEMPORARY(b, true); + SDO_GEOR.GETRASTERSUBSET + ( + georaster => g, + pyramidlevel => 0, + window => sdo_number_array(0,0,699,899), + bandnumbers => '0', + rasterBlob => b + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-10.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-10.sql new file mode 100644 index 0000000..8daf058 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-10.sql @@ -0,0 +1,17 @@ +-- Listing D-10. Georeferencing a GeoRaster Object +DECLARE + g SDO_GEORASTER; + b BLOB; +BEGIN + SELECT georaster INTO g FROM branches WHERE id = 1; + SDO_GEOR.GEOREFERENCE + ( + georaster => g, + srid => 8307, + modelcoordinatelocation => 0, -- 0 for center of the picture + xCoefficients => sdo_number_array(30, 0, 410000.0), -- values for a, b, and c + yCoefficients => sdo_number_array(0, -30, 3759000.0) -- values for d, e, and f + ); + UPDATE branches SET georaster = g WHERE id = 1; +END; +/ diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-11.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-11.sql new file mode 100644 index 0000000..aefc01a --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-11.sql @@ -0,0 +1,10 @@ +-- Listing D-11. Generating and Populating the Spatial Extent of the georaster Column +DECLARE + extent SDO_GEOMETRY; +BEGIN + SELECT SDO_GEOR.GENERATESPATIALEXTENT(a.georaster) INTO extent + FROM branches a WHERE a.id=1 FOR UPDATE; + UPDATE branches a SET a.georaster.spatialextent = extent WHERE a.id=1; +COMMIT; +END; +/ diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-12.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-12.sql new file mode 100644 index 0000000..fe6f1f7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-12.sql @@ -0,0 +1,14 @@ +-- Listing D-12. Populating the Metadata for the Spatial Extent of the georaster Column +INSERT INTO USER_SDO_GEOM_METADATA +VALUES +( + 'BRANCHES', + 'GEORASTER.SPATIALEXTENT', + SDO_DIM_ARRAY + ( + SDO_DIM_ELEMENT('X', -180, 180, 0.5), + SDO_DIM_ELEMENT('Y', -90, 90, 5) + ), + 8307 -- SRID +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-13.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-13.sql new file mode 100644 index 0000000..017c4fa --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-13.sql @@ -0,0 +1,3 @@ +-- Listing D-13. Creating an Index on the Spatial Extent of the georaster Column +CREATE INDEX geor_idx ON branches(georaster.spatialextent) + INDEXTYPE IS MDSYS.SPATIAL_INDEX; diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-14.sql b/ProOracleSpatialCode/Code/Appendix-D/listing-D-14.sql new file mode 100644 index 0000000..7a808a8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-14.sql @@ -0,0 +1,13 @@ +-- Listing D-14. Creating a Predefined Theme for the georaster Column in the branches Table +INSERT INTO user_sdo_themes +VALUES +( +'BRANCHES_Images', -- Theme name +'Tiff Image', -- Description +'BRANCHES', -- Base table name +'GEORASTER', -- Column name storing georaster object in table +' + +' -- Theme style definition +); diff --git a/ProOracleSpatialCode/Code/Appendix-D/listing-D-15.xml b/ProOracleSpatialCode/Code/Appendix-D/listing-D-15.xml new file mode 100644 index 0000000..d1d9145 --- /dev/null +++ b/ProOracleSpatialCode/Code/Appendix-D/listing-D-15.xml @@ -0,0 +1,11 @@ + + + + SELECT georaster FROM branches WHERE id =1 + + diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-01.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-01.sql new file mode 100644 index 0000000..5bc5fb7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-01.sql @@ -0,0 +1,7 @@ +-- Listing 2-1. Creating the us_restaurants_new Table +CREATE TABLE us_restaurants_new +( + id NUMBER, + poi_name VARCHAR2(32), + location SDO_GEOMETRY -- New column to store locations +); diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-02.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-02.sql new file mode 100644 index 0000000..49a9c56 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-02.sql @@ -0,0 +1,20 @@ +-- Listing 2-2. Inserting a Value for the SDO_GEOMETRY Column in an Oracle Table +INSERT INTO us_restaurants_new VALUES +( + 1, + 'PIZZA HUT', + SDO_GEOMETRY + ( + 2001, -- SDO_GTYPE attribute: "2" in 2001 specifies dimensionality is 2. + NULL, -- other fields are set to NULL. + SDO_POINT_TYPE -- Specifies the coordinates of the point + ( + -87, -- first ordinate, i.e., value in longitude dimension + -78, -- second ordinate, i.e., value in latitude dimension + NULL -- third ordinate, if any + ), + NULL, + NULL + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-03.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-03.sql new file mode 100644 index 0000000..b5eb7fb --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-03.sql @@ -0,0 +1,13 @@ +-- Listing 2-3. Converting Address Data (Implicit Spatial Information) to the SDO_GEOMETRY (Explicit Spatial Information) Object +SELECT +SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', -- Spatial schema storing the geocoder data + SDO_KEYWORDARRAY -- Object combining different address components + ( + '3746 CONNECTICUT AVE NW', + 'WASHINGTON, DC 20008' + ), + 'US' -- Name of the country +) geom +FROM DUAL ; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-04.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-04.sql new file mode 100644 index 0000000..ce5311b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-04.sql @@ -0,0 +1,11 @@ +-- Listing 2-4. Finding the Five Nearest Restaurants on I-795 +SELECT poi_name +FROM + ( + SELECT poi_name, + SDO_GEOM.SDO_DISTANCE(P.location, I.geom, 0.5) distance + FROM us_interstates I, us_restaurants P + WHERE I.interstate = 'I795' + ORDER BY distance + ) +WHERE ROWNUM <= 5; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-05.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-05.sql new file mode 100644 index 0000000..b400374 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-05.sql @@ -0,0 +1,4 @@ +-- Listing 2-5. Creating an Index on Locations (SDO_GEOMETRY Column) of Restaurants +DROP INDEX us_restaurants_sidx; +CREATE INDEX us_restaurants_sidx ON us_restaurants(location) + INDEXTYPE IS mdsys.spatial_index; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-06.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-06.sql new file mode 100644 index 0000000..fdc2ef5 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-06.sql @@ -0,0 +1,6 @@ +-- Listing 2-6. Finding the Five Nearest Restaurants on Interstate I-795 Using the Spatial Index +SELECT poi_name +FROM us_interstates I, us_restaurants P +WHERE I.interstate = 'I795' + AND SDO_NN(P.location, I.geom) ='TRUE' + AND ROWNUM <= 5; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-07.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-07.sql new file mode 100644 index 0000000..c05b90e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-07.sql @@ -0,0 +1,10 @@ +-- Listing 2-7. Identifying All Restaurants in a 50 km Radius Around Interstate I-795 +SELECT POI_NAME +FROM us_interstates I, us_restaurants P +WHERE + SDO_ANYINTERACT + ( + P.location, + SDO_GEOM.SDO_BUFFER(I.geom, 50, 0.5, 'UNIT=KM') + ) ='TRUE' +AND I.interstate='I795' ; diff --git a/ProOracleSpatialCode/Code/Chapter-02/listing-02-08.sql b/ProOracleSpatialCode/Code/Chapter-02/listing-02-08.sql new file mode 100644 index 0000000..12effa4 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-02/listing-02-08.sql @@ -0,0 +1,4 @@ +-- Listing 2-8. Verifying That a Spatial Install Is Successful +SELECT COMP_NAME, STATUS +FROM DBA_REGISTRY +WHERE COMP_NAME = 'Spatial'; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-01.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-01.sql new file mode 100644 index 0000000..f104811 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-01.sql @@ -0,0 +1,15 @@ +-- Listing 3-1. Creating the customers Table +CREATE TABLE customers +( + id NUMBER, + datasrc_id NUMBER, + name VARCHAR2(35), + category VARCHAR2(30), + street_number VARCHAR2(5), + street_name VARCHAR2(60), + city VARCHAR2(32), + postal_code VARCHAR2(16), + state VARCHAR2(32), + phone_number VARCHAR2(15), + customer_grade VARCHAR2(15) +); diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-02.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-02.sql new file mode 100644 index 0000000..60a1d93 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-02.sql @@ -0,0 +1,16 @@ +-- Listing 3-2. Populating customers table. +INSERT INTO customers VALUES +( + 1, -- id + 1, -- datasrc_id + 'Pizza Hut', -- name + 'Restaurant', -- restaurant + '134', -- street_number + '12TH STREET', -- street_name + 'WASHINGTON', -- city + '20003', -- postal_code + 'DC', -- state + NULL, -- phone_number + 'GOLD' -- customer_grade +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-03.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-03.sql new file mode 100644 index 0000000..6487daa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-03.sql @@ -0,0 +1,2 @@ +-- Listing 3-3. Adding a location Column to the customers Table +ALTER TABLE customers ADD (location SDO_GEOMETRY); diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-04.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-04.sql new file mode 100644 index 0000000..43b094a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-04.sql @@ -0,0 +1,4 @@ +-- Listing 3-4. Sample Address for a Specific Customer in the customers Table +SELECT street_number, street_name, city, state, postal_code +FROM customers +WHERE id = 1; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-05.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-05.sql new file mode 100644 index 0000000..c7b4e53 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-05.sql @@ -0,0 +1,14 @@ +-- Listing 3-5. Geocoding Addresses to Obtain Explicit Spatial Information +UPDATE customers +SET location = + sdo_gcdr.geocode_as_geometry + ( + 'SPATIAL', + sdo_keywordarray + ( + street_number || ' ' || street_name, + city || ', ' || state || ' ' || postal_code + ), + 'US' + ); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-06.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-06.sql new file mode 100644 index 0000000..459f53d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-06.sql @@ -0,0 +1,4 @@ +-- Listing 3-6. Geocoded location Column in the customers Table +SELECT location +FROM customers +WHERE id = 1; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-07.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-07.sql new file mode 100644 index 0000000..30c7194 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-07.sql @@ -0,0 +1,13 @@ +-- Listing 3-7. Updating a location Column Using an SDO_GEOMETRY Constructor +UPDATE customers +SET location = + SDO_GEOMETRY + ( + 2001, + 8307, + SDO_POINT_TYPE(-77.06, 38.94, NULL), + NULL, + NULL + ) +WHERE id=1; +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-08.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-08.sql new file mode 100644 index 0000000..c88def1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-08.sql @@ -0,0 +1,13 @@ +-- Listing 3-8. Creating the us_states Table +CREATE TABLE us_states +( + state VARCHAR2(26), + state_abrv VARCHAR2(2), + totpop NUMBER, + landsqmi NUMBER, + poppssqmi NUMBER, + medage NUMBER, + medhhinc NUMBER, + avghhinc NUMBER, + geom SDO_GEOMETRY +); diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-09.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-09.sql new file mode 100644 index 0000000..efbbfb9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-09.sql @@ -0,0 +1,12 @@ +-- Listing 3-9. Creating the us_counties Table +CREATE TABLE us_counties +( + id NUMBER NOT NULL, + county VARCHAR2(31), + state VARCHAR2(30), + state_abrv VARCHAR2(2), + landsqmi NUMBER, + totpop NUMBER, + poppsqmi NUMBER, + geom SDO_GEOMETRY +); diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-10.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-10.sql new file mode 100644 index 0000000..c23f43d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-10.sql @@ -0,0 +1,15 @@ +-- Listing 3-10. Creating the us_interstates Table +CREATE TABLE us_interstates +( + id NUMBER, + interstate VARCHAR2(35), + geom SDO_GEOMETRY +); +CREATE TABLE us_streets +( + id NUMBER, + street_name VARCHAR2(35), + city VARCHAR2(32), + state VARCHAR2(32), + geom SDO_GEOMETRY +); diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-11.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-11.sql new file mode 100644 index 0000000..a2348c0 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-11.sql @@ -0,0 +1,2 @@ +-- Listing 3-11. The USER_SDO_GEOM_METADATA View +DESCRIBE USER_SDO_GEOM_METADATA; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-12.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-12.sql new file mode 100644 index 0000000..a8e45f6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-12.sql @@ -0,0 +1,4 @@ +-- Listing 3-12: Selecting srids of Geodetic Coordinate Systems. +SELECT SRID +FROM MDSYS.CS_SRS +WHERE WKTEXT LIKE 'GEOGCS%'; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-13.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-13.sql new file mode 100644 index 0000000..9b2d78b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-13.sql @@ -0,0 +1,4 @@ +-- Listing 3-13: Selecting srids of Projected Coordinate Systems. +SELECT SRID +FROM MDSYS.CS_SRS +WHERE WKTEXT LIKE 'PROJCS%'; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-14.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-14.sql new file mode 100644 index 0000000..c275029 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-14.sql @@ -0,0 +1,2 @@ +-- Listing 3-14. The SDO_DIM_ARRAY Structure +DESCRIBE SDO_DIM_ARRAY; diff --git a/ProOracleSpatialCode/Code/Chapter-03/listing-03-15.sql b/ProOracleSpatialCode/Code/Chapter-03/listing-03-15.sql new file mode 100644 index 0000000..31bc73d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-03/listing-03-15.sql @@ -0,0 +1,26 @@ +-- Listing 3-15. Inserting Metadata for the Spatial Layer Corresponding to the location Column of the customers Table +INSERT INTO USER_SDO_GEOM_METADATA +VALUES +( + 'CUSTOMERS', -- TABLE_NAME + 'LOCATION', -- COLUMN_NAME + SDO_DIM_ARRAY -- DIMINFO attribute for storing dimension bounds, tolerance + ( + SDO_DIM_ELEMENT + ( + 'LONGITUDE', -- DIMENSION NAME for first dimension + -180, -- SDO_LB for the dimension + 180, -- SDO_UB for the dimension + 0.5 -- Tolerance of 0.5 meters + ), + SDO_DIM_ELEMENT + ( + 'LATITUDE', -- DIMENSION NAME for second dimension + -90, -- SDO_LB for the dimension + 90, -- SDO_UB for the dimension + 0.5 -- Tolerance of 0.5 meters + ) + ), + 8307 -- SRID value for specifying a geodetic coordinate system +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-01.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-01.sql new file mode 100644 index 0000000..be25f9e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-01.sql @@ -0,0 +1,7 @@ +-- Listing 4-1: Creating a table to store all geometry examples +CREATE TABLE geometry_examples +( + name VARCHAR2(100), + description VARCHAR2(100), + geom SDO_GEOMETRY +); diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-02.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-02.sql new file mode 100644 index 0000000..c2a21f2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-02.sql @@ -0,0 +1,2 @@ +-- Listing 4-2. SDO_GEOMETRY Data type in Oracle +DESCRIBE SDO_GEOMETRY diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-03.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-03.sql new file mode 100644 index 0000000..db43430 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-03.sql @@ -0,0 +1,4 @@ +-- Listing 4-3: Example of SDO_GTYPE in the location column of customers table. +SELECT a.location.sdo_gtype +FROM customers a +WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-04.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-04.sql new file mode 100644 index 0000000..3866756 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-04.sql @@ -0,0 +1,4 @@ +-- Listing 4-4. Example of SDO_GTYPE in the geom Column of us_interstates table +SELECT a.geom.sdo_gtype +FROM us_interstates a +WHERE rownum=1; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-05.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-05.sql new file mode 100644 index 0000000..c2e8a2d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-05.sql @@ -0,0 +1,4 @@ +-- Listing 4-5: Example of SDO_GTYPE in the location column of us_states table. +SELECT a.geom.sdo_gtype +FROM us_states a +WHERE state_abrv='NH'; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-06.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-06.sql new file mode 100644 index 0000000..cd21460 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-06.sql @@ -0,0 +1,4 @@ +-- Listing 4-6: Example of SDO_GTYPE in the location column of us_states table. +SELECT a.geom.sdo_gtype +FROM us_states a +WHERE state_abrv='TX'; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-07.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-07.sql new file mode 100644 index 0000000..eef79ce --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-07.sql @@ -0,0 +1,2 @@ +-- Listing 4-7. The MDSYS.CS_SRS Table +DESCRIBE MDSYS.CS_SRS diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-08.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-08.sql new file mode 100644 index 0000000..78163ea --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-08.sql @@ -0,0 +1,7 @@ +-- Listing 4-8. Selecting an SRID for the Southern Texas Region from the MDSYS.CS_SRS Table +SELECT cs_name, srid, wktext + FROM MDSYS.CS_SRS + WHERE WKTEXT LIKE 'PROJCS%' + AND CS_NAME LIKE '%Texas%' + AND CS_NAME LIKE '%Southern%' + AND ROWNUM=1; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-09.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-09.sql new file mode 100644 index 0000000..1055fce --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-09.sql @@ -0,0 +1,2 @@ +-- Listing 4-9. SDO_POINT_TYPE Data Type +DESCRIBE SDO_POINT_TYPE diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-10.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-10.sql new file mode 100644 index 0000000..3115335 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-10.sql @@ -0,0 +1,20 @@ +-- Listing 4-10. Point Data in geometry_examples +INSERT INTO geometry_examples (name, description, geom) VALUES +( + 'POINT', + '2-dimensional Point at coordinates (-79,37) with srid set to 8307', + SDO_GEOMETRY + ( + 2001, -- SDO_GTYPE format: D00T. Set to 2001 for a 2-dimensional point + 8307, -- SDO_SRID (geodetic) + SDO_POINT_TYPE + ( + -79, -- ordinate value for Longitude + 37, -- ordinate value Latitude + NULL -- no third dimension (only 2 dimensions) + ), + NULL, + NULL + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-11.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-11.sql new file mode 100644 index 0000000..66c1732 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-11.sql @@ -0,0 +1,2 @@ +-- Listing 4-11. Constructing a Point Geometry Using Well-Known Text (SQL/MM) +SELECT SDO_GEOMETRY(' POINT(-79 37) ', 8307) geom FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-12.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-12.sql new file mode 100644 index 0000000..ef42f3e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-12.sql @@ -0,0 +1,24 @@ +-- Listing 4-12. Storing the Point Coordinates in the SDO_ORDINATES Array Instead of SDO_POINT +INSERT INTO geometry_examples VALUES +( + '2-D POINT stored in SDO_ORDINATES', + '2-dimensional Point at coordinates (-79, 37) with srid set to 8307', + SDO_GEOMETRY + ( + 2001, -- SDO_GTYPE format: D00T. Set to 2001 for as a 2-dimensional point + 8307, -- SDO_SRID + NULL, -- SDO_POINT attribute set to NULL + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 1, -- Element-type is 1 for a point + 1 -- Interpretation specifies # of points. In this case 1. + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + -79, -- Ordinate value for Longitude + 37 -- Ordinate value for Latitude + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-13.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-13.sql new file mode 100644 index 0000000..ab327eb --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-13.sql @@ -0,0 +1,17 @@ +-- Listing 4-13. Four-Dimensional Point Example +INSERT INTO geometry_examples VALUES +( + '4-D POINT', + '4-dimensional Point at (Xa=>2, Ya=>2, Za=>2, La=>2) with srid set to NULL', + SDO_GEOMETRY + ( + 4001, -- SDO_GTYPE: D00T. Set to 4001 as it is a 4-dimensional point + NULL, -- SDO_SRID + NULL, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY + (1,1,1), -- Indicates a point element + SDO_ORDINATE_ARRAY + (2,2,2,2) -- Store the four ordinates here + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-14.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-14.sql new file mode 100644 index 0000000..0db40de --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-14.sql @@ -0,0 +1,25 @@ +-- Listing 4-14. Two-Dimensional Line String Example +INSERT INTO geometry_examples VALUES +( + 'LINE STRING', + '2-D line string connecting A(Xa=>1,Ya=>1),B(Xb=>2, Yb=>2), C(Xc=>2,Yc=>1)', + SDO_GEOMETRY + ( + 2002, -- SDO_GTYPE: D00T. Set to 2002 as it is a 2-dimensional line string + 32774, -- SDO_SRID + NULL, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 2, -- Element-type is 2 for a LINE STRING + 1 -- Interpretation is 1 if line string is connected by straight lines. + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + 1,1, -- Xa, Ya values + 2,2, -- Xb, Yb values + 2,1 -- Xc, Yc values + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-15.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-15.sql new file mode 100644 index 0000000..6557475 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-15.sql @@ -0,0 +1,25 @@ +-- Listing 4-15. Two-Dimensional Line String Connected by Arcs +INSERT INTO geometry_examples VALUES +( + 'ARCSTRING', + '2-D arc connecting A(Xa=>1,Ya=>1),B(Xb=>2, Yb=>2), C(Xc=>2,Yc=>1)', + SDO_GEOMETRY + ( + 2002, -- SDO_GTYPE: D00T. Set to 2002 as it is a 2-dimensional line string + 32774, -- SDO_SRID + NULL, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 2, -- Element-type is 2 for a LINE STRING + 2 -- Interpretation is 2 if line string is connected by ARCs. + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + 1,1, -- Xa, Ya values + 2,2, -- Xb, Yb values + 2,1 -- Xc, Yc values + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-16.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-16.sql new file mode 100644 index 0000000..35499be --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-16.sql @@ -0,0 +1,27 @@ +-- Listing 4-16. Example of a Simple Polygon Connected by Lines +INSERT INTO geometry_examples VALUES +( + 'POLYGON', + '2-D polygon connecting A(Xa, Ya), B(Xb, Yb), C(Xc, Yc), D(Xd, Yd)', + SDO_GEOMETRY + ( + 2003, -- SDO_GTYPE: D00T. Set to 2003 as it is a 2-dimensional polygon + 32774, -- SDO_SRID + NULL, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 1003, -- Element-type is 1003 for an outer POLYGON element + 1 -- Interpretation is 1 if boundary is connected by straight lines. + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + 1,1, -- Xa, Ya values + 2,-1, -- Xb, Yb values + 3,1, -- Xc, Yc values + 2,2, -- Xd, Yd values + 1,1 -- Xa, Ya values : Repeat first vertex to close the ring + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-17.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-17.sql new file mode 100644 index 0000000..f02bc38 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-17.sql @@ -0,0 +1,24 @@ +-- Listing 4-17. Rectangular Polygon Example +INSERT INTO geometry_examples VALUES +( + 'RECTANGLE POLYGON', + '2-D rectangle polygon with corner points A(Xa, Ya), C (Xc, Yc)', + SDO_GEOMETRY + ( + 2003, -- SDO_GTYPE: D00T. Set to 2003 as it is a 2-dimensional polygon + 32774, -- SDO_SRID + null, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 1003, -- Element-type is 1003 for (an outer) POLYGON + 3 -- Interpretation is 3 if polygon is a RECTANGLE + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + 1,1, -- Xa, Ya values + 2,2 -- Xc, Yc values + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-04/listing-04-18.sql b/ProOracleSpatialCode/Code/Chapter-04/listing-04-18.sql new file mode 100644 index 0000000..ddb04b3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-04/listing-04-18.sql @@ -0,0 +1,25 @@ +-- Listing 4-18. Circular Polygon Example +INSERT INTO geometry_examples VALUES +( + 'CIRCLE POLYGON', + '2-D circle polygon with 3 boundary points A(Xa,Ya), B(Xb,Yb), C(Xc,Yc)', + SDO_GEOMETRY + ( + 2003, -- SDO_GTYPE: D00T. Set to 2003 as it is a 2-dimensional polygon + 32774, -- SDO_SRID + NULL, -- SDO_POINT_TYPE is null + SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values) + ( + 1, -- Offset is 1 + 1003, -- Element-type is 1003 for (an outer) POLYGON + 4 -- Interpretation is 4 if polygon is a CIRCLE + ), + SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute + ( + 1,1, -- Xa, Ya values + 3,1, -- Xb, Yb values + 2,2 -- Xc, Yc values + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-01.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-01.sql new file mode 100644 index 0000000..3e4da53 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-01.sql @@ -0,0 +1,6 @@ +-- Listing 5-1. Creating the sales_regions Table +CREATE TABLE sales_regions +( + id NUMBER, + geom SDO_GEOMETRY +); diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-02.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-02.sql new file mode 100644 index 0000000..7b5a4b2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-02.sql @@ -0,0 +1,24 @@ +-- Listing 5-2. Inserting a Polygon Geometry into the sales_regions Table +INSERT INTO sales_regions VALUES +( + 10000, -- SALES_REGIONS ID + SDO_GEOMETRY -- use the SDO_GEOMETRY constructor + ( + 2003, -- A two-dimensional Polygon + 8307, -- SRID is GEODETIC + NULL, -- SDO_POINT_TYPE is null as it is not a point + SDO_ELEM_INFO_ARRAY (1, 1003, 1), -- A polygon with just one ring + SDO_ORDINATE_ARRAY -- SDO_ORDINATES field + ( + -77.04487, 38.9043742, -- coordinates of first vertex + -77.046645, 38.9040983, -- other vertices + -77.04815, 38.9033127, -77.049155, 38.9021368, + -77.049508, 38.9007499, -77.049155, 38.899363, -77.048149, 38.8981873, + -77.046645, 38.8974017, -77.04487, 38.8971258, -77.043095, 38.8974017, + -77.041591, 38.8981873, -77.040585, 38.899363, -77.040232, 38.9007499, + -77.040585, 38.9021368, -77.04159, 38.9033127, -77.043095, 38.9040983, + -77.04487, 38.9043742 -- coordinates of last vertex same as first vertex + ) + ) +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-03.ctl b/ProOracleSpatialCode/Code/Chapter-05/listing-05-03.ctl new file mode 100644 index 0000000..94a4636 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-03.ctl @@ -0,0 +1,22 @@ +-- Listing 5-3. Control File for Loading "Point" sales_regions Data +LOAD DATA +INFILE * +INTO TABLE sales_regions +APPEND +FIELDS TERMINATED BY '|' +TRAILING NULLCOLS +( + id NULLIF ID = BLANKS, + geom COLUMN OBJECT + ( + SDO_GTYPE INTEGER EXTERNAL, + SDO_POINT COLUMN OBJECT + ( + X FLOAT EXTERNAL, + Y FLOAT EXTERNAL + ) + ) +) +BEGINDATA +1|2001|-76.99022|38.888654| +2|2001|-77.41575|38.924753| diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-04.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-04.bat new file mode 100644 index 0000000..4af4819 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-04.bat @@ -0,0 +1,2 @@ +REM Listing 5-4. Using SQL*Loader to Load Data into the sales_regions Table +SQLLDR spatial/spatial CONTROL=sales_regions.ctl diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-05.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-05.bat new file mode 100644 index 0000000..3b87b31 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-05.bat @@ -0,0 +1,2 @@ +REM Listing 5-5. Using SQL*Loader with a Data File +SQLLDR spatial/spatial CONTROL=sales_regions.ctl DATA=sales_regions.dat diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-06.ctl b/ProOracleSpatialCode/Code/Chapter-05/listing-05-06.ctl new file mode 100644 index 0000000..1b9cc0c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-06.ctl @@ -0,0 +1,19 @@ +-- Listing 5-6. sales_regions.ctl File +LOAD DATA +INFILE sales_regions.dat +INTO TABLE sales_regions +APPEND +FIELDS TERMINATED BY '|' +TRAILING NULLCOLS +( + id NULLIF ID = BLANKS, + geom COLUMN OBJECT + ( + SDO_GTYPE INTEGER EXTERNAL, + SDO_POINT COLUMN OBJECT + ( + X FLOAT EXTERNAL, + Y FLOAT EXTERNAL + ) + ) +) diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-07.dat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-07.dat new file mode 100644 index 0000000..b90bf71 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-07.dat @@ -0,0 +1,2 @@ +1|2001|-76.99022|38.888654| +2|2001|-77.41575|38.924753| diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-08.ctl b/ProOracleSpatialCode/Code/Chapter-05/listing-05-08.ctl new file mode 100644 index 0000000..ddce640 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-08.ctl @@ -0,0 +1,27 @@ +-- Listing 5-8. Control File for Loading Nonpoint SDO_GEOMETRY Data +LOAD DATA +INFILE * +CONTINUEIF NEXT(1:1)='#' +INTO TABLE sales_regions +APPEND +FIELDS TERMINATED BY '|' +TRAILING NULLCOLS +( + id CHAR(6), + geom COLUMN OBJECT + ( + SDO_GTYPE INTEGER EXTERNAL, + SDO_SRID INTEGER EXTERNAL, + SDO_ELEM_INFO VARRAY terminated by '/' (E FLOAT EXTERNAL), + SDO_ORDINATES VARRAY terminated by '/' (O FLOAT EXTERNAL) + ) +) +BEGINDATA +10000| 2003| 8307| +#1| 1003| 1|/ +#-77.04487| 38.9043742| -77.046645| 38.9040983| -77.04815| 38.9033127|-77.049155| +#38.9021368| -77.049508| 38.9007499| -77.049155| 38.899363| -77.048149| +#38.8981873| -77.046645| 38.8974017| -77.04487| 38.8971258| -77.043095| +#38.8974017| -77.041591| 38.8981873| -77.040585| 38.899363| -77.040232| +#38.9007499| -77.040585| 38.9021368| -77.04159| 38.9033127| -77.043095| +#38.9040983| -77.04487| 38.9043742| -77.04487| 38.9043742|/ diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-09.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-09.bat new file mode 100644 index 0000000..83c1d9f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-09.bat @@ -0,0 +1,2 @@ +REM Listing 5-9. Exporting the customers Table into the customers.dmp File +EXP spatial/spatial FILE=customers.dmp TABLES=customers diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-10.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-10.bat new file mode 100644 index 0000000..e654664 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-10.bat @@ -0,0 +1,2 @@ +REM Listing 5-10. Importing the customers Table into the scott Schema +IMP scott/tiger FILE=customers.dmp IGNORE=Y INDEXES=N TABLES=CUSTOMERS diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-11.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-11.bat new file mode 100644 index 0000000..764fe19 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-11.bat @@ -0,0 +1,2 @@ +REM Listing 5-11. Importing Using the fromuser and touser Arguments +IMP SYSTEM/MANAGER FROMUSER=spatial TOUSER=scott FILE=customers.dmp diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-12.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-12.bat new file mode 100644 index 0000000..0a0ef68 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-12.bat @@ -0,0 +1,8 @@ +REM Listing 5-12. Transporting the Tablespace TBS from a Source Database +SQLPLUS spatial/spatial +EXECUTE SDO_UTIL.PREPARE_FOR_TTS('TBS'); +CONNECT SYS/CHANGE_ON_INSTALL AS SYSDBA +EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('TBS', TRUE); +ALTER TABLESPACE TBS READ ONLY; +EXIT; +EXP USERID = "'SYS/CHANGE_ON_INSTALL AS SYSDBA'" TRANSPORT_TABLESPACE=Y TABLESPACES=TBS FILE=trans_ts.dmp diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-13.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-13.bat new file mode 100644 index 0000000..c0637da --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-13.bat @@ -0,0 +1,2 @@ +REM Listing 5-13. Creating the Transported Tablespace in the Target Database +IMP USERID = "'SYS/CHANGE_ON_INSTALL'" TRANSPORT_TABLESPACE=Y FILE=trans_ts.dmp DATAFILES='sdo_tts.dbf' TABLESPACES=tbs diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-14.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-14.bat new file mode 100644 index 0000000..81427a1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-14.bat @@ -0,0 +1,5 @@ +REM Listing 5-14. Enabling Spatial Indexes for the Tables in the Transported Tablespace +SQLPLUS SYS/CHANGE_ON_INSTALL AS SYSDBA +ALTER TABLESPACE TBS READ WRITE; +CONNECT spatial/spatial; +EXEC SDO_UTIL.INITIALIZE_INDEXES_FOR_TTS; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-15.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-15.sql new file mode 100644 index 0000000..0459daa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-15.sql @@ -0,0 +1,2 @@ +-- Listing 5-15. Rebuilding a Spatial Index After Transporting Across Endian Platforms +ALTER INDEX customers_sidx REBUILD; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-16.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-16.sql new file mode 100644 index 0000000..da91e4d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-16.sql @@ -0,0 +1,2 @@ +-- Listing 5-16. Migrating location Column Data in the customers Table to the Current Format (10g) +EXECUTE SDO_MIGRATE.TO_CURRENT('customers', 'location', 100); diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-17.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-17.bat new file mode 100644 index 0000000..05e7c61 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-17.bat @@ -0,0 +1,2 @@ +REM Listing 5-17. Using shp2sdo to Convert from ESRI Shapefiles +SHP2SDO customers -g location -x(-180,180) -y(-90,90) -s 8307 -t 0.5 diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-18.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-18.sql new file mode 100644 index 0000000..5c99a4c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-18.sql @@ -0,0 +1,26 @@ +-- Listing 5-18. customers.sql File +CREATE TABLE customers +( + id NUMBER, + datasrc_id NUMBER, + name VARCHAR2(35), + category VARCHAR2(30), + street_number VARCHAR2(5), + street_name VARCHAR2(60), + city VARCHAR2(32), + postal_code VARCHAR2(16), + state VARCHAR2(32), + phone_number VARCHAR2(15), + customer_grade VARCHAR2(15) +); +INSERT INTO USER_SDO_GEOM_METADATA VALUES +( + 'CUSTOMERS', -- Table_name + 'LOCATION', -- Column name + MDSYS.SDO_DIM_INFO_ARRAY -- Diminfo + ( + MDSYS.SDO_DIM_ELEMENT('Longitude', -180, 180, 0.5), --Longitude dimension + MDSYS.SDO_DIM_ELEMENT('Latitude', -90, 90, 0.5) --Latitude dimension + ), + 8307 -- Geodetic SRID +); diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-19.bat b/ProOracleSpatialCode/Code/Chapter-05/listing-05-19.bat new file mode 100644 index 0000000..9982369 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-19.bat @@ -0,0 +1,3 @@ +REM Listing 5-19. Executing the Output Files from SHP2SDO to Load Data into Oracle +SQLPLUS spatial/spatial @customers.sql +SQLLDR spatial/spatial CONTROL=customers.ctl diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-20.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-20.sql new file mode 100644 index 0000000..9f2493c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-20.sql @@ -0,0 +1,4 @@ +-- Listing 5-20. Converting from an SDO_GEOMETRY to WKT Format +SELECT a.location.GET_WKT() wkt +FROM customers a +WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-21.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-21.sql new file mode 100644 index 0000000..115a64d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-21.sql @@ -0,0 +1,4 @@ +-- Listing 5-21. Publishing an SDO_GEOMETRY to a GML Document +SELECT TO_CHAR(SDO_UTIL.TO_GMLGEOMETRY(location)) gml_location +FROM customers +WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-22.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-22.sql new file mode 100644 index 0000000..ae27d62 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-22.sql @@ -0,0 +1,9 @@ +-- Listing 5-22. Publishing Multiple Geometries to a GML Document Fragment +SELECT xmlelement("State", xmlattributes('http://www.opengis.net/gml' as "xmlns:gml"), + xmlforest( + state as "Name", + totpop as "Population", + xmltype(sdo_util.to_gmlgeometry(geom)) as "gml:geometryProperty")) +AS theXMLElements +FROM spatial.us_states +WHERE state_abrv in ('DE', 'UT'); diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-24.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-24.sql new file mode 100644 index 0000000..9961f3a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-24.sql @@ -0,0 +1,4 @@ +-- Listing 5-24. Validation Check on a Geometry from the sales_regions Table +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(a.geom, 0.5) is_valid +FROM sales_regions a +WHERE a.id=10000; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-25.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-25.sql new file mode 100644 index 0000000..aca06c3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-25.sql @@ -0,0 +1,26 @@ +-- Listing 5-25. Validation on a Self-Crossing Geometry +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT +( + SDO_GEOMETRY + ( + 2003, + NULL, + NULL, + SDO_ELEM_INFO_ARRAY + ( + 1, 1003,1 -- Polygonal ring connected by lines + ), + SDO_ORDINATE_ARRAY + ( + 2,2, -- first vertex + 3,3.5, -- second vertex. Edge 1 is between previous and this vertex. + 2,5, + 5,5, + 3,3.5, -- fifth vertex. Edge 4 is between previous and this vertex. + 5,2, + 2,2 + ) + ), + 0.000005 +) +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-26.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-26.sql new file mode 100644 index 0000000..3a8e255 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-26.sql @@ -0,0 +1,18 @@ +-- Listing 5-26. Using the diminfo Parameter in the VALIDATE_GEOMETRY_WITH_CONTEXT Function +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT +( + SDO_GEOMETRY -- first argument to validate is geometry + ( + 2001, -- point type + NULL, + SDO_POINT_TYPE(-80,20,NULL), -- point is <80,20> and is out of range. + NULL, + NULL + ), + SDO_DIM_ARRAY -- second argument is diminfo (of type SDO_DIM_ARRAY) + ( + SDO_DIM_ELEMENT('X', 0, 50, 0.5), -- lower, upper bound range is 0 to 50 + SDO_DIM_ELEMENT('Y', 0, 50, 0.5) -- lower, upper bound range is 0 to 50 + ) +) is_valid +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-28.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-28.sql new file mode 100644 index 0000000..1407c17 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-28.sql @@ -0,0 +1,12 @@ +-- Listing 5-28. Using the VALIDATE_LAYER_WITH_CONTEXT Procedure +CREATE TABLE validate_results(sdo_rowid ROWID, status VARCHAR2(2000)); +BEGIN + SDO_GEOM.VALIDATE_LAYER_WITH_CONTEXT + ( + 'SALES_REGIONS', + 'GEOM', + 'VALIDATE_RESULTS' + ); +END; +/ +SELECT * FROM validate_results; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-29.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-29.sql new file mode 100644 index 0000000..1deb225 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-29.sql @@ -0,0 +1,4 @@ +-- Listing 5-29. Example of Removing Duplicate Vertices in a Geometry +SELECT geom, SDO_UTIL.REMOVE_DUPLICATE_VERTICES(a.geom,0.5) nodup_geom +FROM sales_regions a +WHERE id=1000; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-30.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-30.sql new file mode 100644 index 0000000..1ffccb8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-30.sql @@ -0,0 +1,8 @@ +-- Listing 5-30. Validating After Removing the Duplicate Vertices +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT +( + SDO_UTIL.REMOVE_DUPLICATE_VERTICES(a.geom, 0.5), + 0.5 +) is_valid +FROM sales_regions a +WHERE id=10000; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-31.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-31.sql new file mode 100644 index 0000000..d01e1c7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-31.sql @@ -0,0 +1,24 @@ +-- Listing 5-31. Extracting the Second Element from a Geometry +SELECT SDO_UTIL.EXTRACT +( + SDO_GEOMETRY + ( + 2007, -- multipolygon collection type geometry + NULL, + NULL, + SDO_ELEM_INFO_ARRAY + ( + 1,1003,3, -- first element descriptor triplet: mbr + 5, 1003, 1 -- second element descriptor triplet: + -- starting offset 5 means it starts at the 5th ordinate + ), + SDO_ORDINATE_ARRAY + ( + 1,1,2,2, -- first element ordinates (four for mbr) + 3,3, 4, 3, 4,4, 3,4, 3,4,3,3 -- second element starting at 5th ordinate: + -- this second element is returned + ) + ), -- End of the Geometry + 2 -- specifies the element number to extract +) second_elem +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-32.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-32.sql new file mode 100644 index 0000000..96a5f62 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-32.sql @@ -0,0 +1,20 @@ +-- Listing 5-32. Validation of an Extracted Geometry +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT +( + SDO_UTIL.EXTRACT + ( + SDO_GEOMETRY + ( + 2007, null, null, + SDO_ELEM_INFO_ARRAY(1,1003,3, 5, 1003, 1), + SDO_ORDINATE_ARRAY + ( + 1,1,2,2, -- first element of multipolygon geometry + 3,3, 4, 3, 4,4, 3,4, 3,4,3,3 -- second element of multipolygon geometry + ) + ), + 2 -- element number to extract + ), + 0.00005 +) +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-33.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-33.sql new file mode 100644 index 0000000..fba0641 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-33.sql @@ -0,0 +1,20 @@ +-- Listing 5-33. Validation on the Result of SDO_UTIL.EXTRACT +SELECT SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT +( + SDO_GEOMETRY + ( + 2003, NULL, NULL, + SDO_ELEM_INFO_ARRAY(1, 1003, 1), + SDO_ORDINATE_ARRAY + ( + 3, 3, -- first vertex coordinates + 4, 3, -- second vertex coordinates + 4, 4, -- third vertex coordinates + 3, 4, -- fourth vertex coordinates + 3, 4, -- fifth vertex coordinates + 3, 3 -- sixth vertex coordinates (same as first for polygon) + ) + ), + 0.00005 -- tolerance +) +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-34.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-34.sql new file mode 100644 index 0000000..086f94d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-34.sql @@ -0,0 +1,20 @@ +-- Listing 5-34. Removing Duplicate Vertices +SELECT SDO_UTIL.REMOVE_DUPLICATE_VERTICES +( + SDO_UTIL.EXTRACT + ( + SDO_GEOMETRY + ( + 2007, NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,3, 5, 1003, 1), + SDO_ORDINATE_ARRAY + ( + 1,1,2,2, + 3,3, 4, 3, 4,4, 3,4, 3,4,3,3 + ) + ), + 2 + ), + 0.00005 +) +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-35.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-35.sql new file mode 100644 index 0000000..b6deeb1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-35.sql @@ -0,0 +1,31 @@ +-- Listing 5-35. Example of SDO_UTIL.APPEND +SELECT +SDO_UTIL.APPEND +( + SDO_UTIL.EXTRACT + ( + SDO_GEOMETRY + ( + 2007, NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,3, 5, 1003, 1), + SDO_ORDINATE_ARRAY(1,1,2,2, + 3,3, 4, 3, 4,4, 3,4, 3,4,3,3) + ), + 1 + ), + SDO_UTIL.REMOVE_DUPLICATE_VERTICES + ( + SDO_GEOMETRY + ( + 2007, NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,3, 5, 1003, 1), + SDO_ORDINATE_ARRAY + ( + 1,1,2,2, + 3,3, 4, 3, 4,4, 3,4, 3,4,3,3 + ) + ), + 0.00005 + ) +) combined_geom +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-05/listing-05-36.sql b/ProOracleSpatialCode/Code/Chapter-05/listing-05-36.sql new file mode 100644 index 0000000..ff3ba5a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-05/listing-05-36.sql @@ -0,0 +1,4 @@ +-- Listing 5-36. Finding the Number of Elements in a Geometry +SELECT SDO_UTIL.GETNUMELEM(geom) nelem +FROM sales_regions +WHERE id=10000; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-01.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-01.sql new file mode 100644 index 0000000..92261f8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-01.sql @@ -0,0 +1,12 @@ +-- Listing 6-1. Geocoding an Address +SELECT SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY + ( + '3746 CONNECTICUT AVE NW', + 'WASHINGTON, DC 20008' + ), + 'US' +) geom +FROM DUAL ; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-02.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-02.sql new file mode 100644 index 0000000..a46b7fe --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-02.sql @@ -0,0 +1,13 @@ +-- Listing 6-2. Geocoding and Normalizing an Address +SELECT SDO_GCDR.GEOCODE +( + 'SPATIAL', + SDO_KEYWORDARRAY + ( + '3746 CONNECTICT AVE NW', + 'WASHINGTON, DC 20348' + ), + 'US', + 'DEFAULT' +) geom +FROM DUAL ; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-03.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-03.sql new file mode 100644 index 0000000..8302c89 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-03.sql @@ -0,0 +1,8 @@ +-- Listing 6-3. Using the GEOCODE_AS_GEOMETRY Function +SELECT SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY('1250 Clay Street', 'San Francisco, CA'), + 'US' +) +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-04.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-04.sql new file mode 100644 index 0000000..91636db --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-04.sql @@ -0,0 +1,8 @@ +-- Listing 6-4. Using the GEOCODE_AS_GEOMETRY Function with an Invalid House Number +SELECT SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY('4500 Clay Street', 'San Francisco, CA'), + 'US' +) +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-05.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-05.sql new file mode 100644 index 0000000..bfe43e7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-05.sql @@ -0,0 +1,8 @@ +-- Listing 6-5. Using the GEOCODE_AS_GEOMETRY Function with an Invalid Street Name +SELECT SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY('Cloy Street', 'San Francisco, CA'), + 'US' +) +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-06.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-06.sql new file mode 100644 index 0000000..96a43a0 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-06.sql @@ -0,0 +1,9 @@ +-- Listing 6-6. Example of Calling the GEOCODE Function +SELECT SDO_GCDR.GEOCODE +( + 'SPATIAL', + SDO_KEYWORDARRAY('Clay Street', 'San Francisco, CA'), + 'US', + 'DEFAULT' +) +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-07.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-07.sql new file mode 100644 index 0000000..92c9eec --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-07.sql @@ -0,0 +1,65 @@ +-- Listing 6-7. FORMAT_GEO_ADDR Procedure +CREATE OR REPLACE PROCEDURE format_geo_addr ( + address SDO_GEO_ADDR +) +AS +BEGIN + dbms_output.put_line ('- ID ' || address.ID); + dbms_output.put_line ('- ADDRESSLINES'); + if address.addresslines.count() > 0 then + for i in 1..address.addresslines.count() loop + dbms_output.put_line ('- ADDRESSLINES['||i||'] ' || address.ADDRESSLINES(i)); + end loop; + end if; + dbms_output.put_line ('- PLACENAME ' || address.PLACENAME); + dbms_output.put_line ('- STREETNAME ' || address.STREETNAME); + dbms_output.put_line ('- INTERSECTSTREET ' || address.INTERSECTSTREET); + dbms_output.put_line ('- SECUNIT ' || address.SECUNIT); + dbms_output.put_line ('- SETTLEMENT ' || address.SETTLEMENT); + dbms_output.put_line ('- MUNICIPALITY ' || address.MUNICIPALITY); + dbms_output.put_line ('- REGION ' || address.REGION); + dbms_output.put_line ('- COUNTRY ' || address.COUNTRY); + dbms_output.put_line ('- POSTALCODE ' || address.POSTALCODE); + dbms_output.put_line ('- POSTALADDONCODE ' || address.POSTALADDONCODE); + dbms_output.put_line ('- FULLPOSTALCODE ' || address.FULLPOSTALCODE); + dbms_output.put_line ('- POBOX ' || address.POBOX); + dbms_output.put_line ('- HOUSENUMBER ' || address.HOUSENUMBER); + dbms_output.put_line ('- BASENAME ' || address.BASENAME); + dbms_output.put_line ('- STREETTYPE ' || address.STREETTYPE); + dbms_output.put_line ('- STREETTYPEBEFORE ' || address.STREETTYPEBEFORE); + dbms_output.put_line ('- STREETTYPEATTACHED ' || address.STREETTYPEATTACHED); + dbms_output.put_line ('- STREETPREFIX ' || address.STREETPREFIX); + dbms_output.put_line ('- STREETSUFFIX ' || address.STREETSUFFIX); + dbms_output.put_line ('- SIDE ' || address.SIDE); + dbms_output.put_line ('- PERCENT ' || address.PERCENT); + dbms_output.put_line ('- EDGEID ' || address.EDGEID); + dbms_output.put_line ('- ERRORMESSAGE ' || address.ERRORMESSAGE); + if address.errormessage is not null and address.errormessage <> 'Not found' then + if substr (address.errormessage,5,1) <> '?' then dbms_output.put_line ('- # House or building number'); end if; + if substr (address.errormessage,6,1) <> '?' then dbms_output.put_line ('- E Street prefix'); end if; + if substr (address.errormessage,7,1) <> '?' then dbms_output.put_line ('- N Street base name'); end if; + if substr (address.errormessage,8,1) <> '?' then dbms_output.put_line ('- U Street suffix'); end if; + if substr (address.errormessage,9,1) <> '?' then dbms_output.put_line ('- T Street type'); end if; + if substr (address.errormessage,10,1) <> '?' then dbms_output.put_line ('- S Secondary unit'); end if; + if substr (address.errormessage,11,1) <> '?' then dbms_output.put_line ('- B Built-up area or city'); end if; + if substr (address.errormessage,14,1) <> '?' then dbms_output.put_line ('- 1 Region'); end if; + if substr (address.errormessage,15,1) <> '?' then dbms_output.put_line ('- C Country'); end if; + if substr (address.errormessage,16,1) <> '?' then dbms_output.put_line ('- P Postal code'); end if; + if substr (address.errormessage,17,1) <> '?' then dbms_output.put_line ('- A Postal add-on code'); end if; + end if; + dbms_output.put_line ('- MATCHCODE ' || address.MATCHCODE || ' = ' || + case address.MATCHCODE + when 1 then 'Exact match' + when 2 then 'Match on city, postal code, street base name and house number' + when 3 then 'Match on city, postal code and street base name' + when 4 then 'Match on city and postal code' + when 10 then 'Match on city but not postal code' + when 11 then 'Match on postal but not on city' + end + ); + dbms_output.put_line ('- MATCHMODE ' || address.MATCHMODE); + dbms_output.put_line ('- LONGITUDE ' || address.LONGITUDE); + dbms_output.put_line ('- LATITUDE ' || address.LATITUDE); +END; +/ +show errors diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-08.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-08.sql new file mode 100644 index 0000000..6e742d5 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-08.sql @@ -0,0 +1,13 @@ +-- Listing 6-8. Example of Using the FORMAT_GEO_ADDR Procedure +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('Clay Street', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-09.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-09.sql new file mode 100644 index 0000000..2a7643b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-09.sql @@ -0,0 +1,6 @@ +-- Listing 6-9. Getting Street Details from the Geocode Reference Data +SELECT road_id, name, postal_code, start_hn, center_hn, end_hn +FROM gc_road_us +WHERE name = 'CLAY ST' +AND postal_code like '94%' +ORDER BY start_hn; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-10.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-10.sql new file mode 100644 index 0000000..4cbfa83 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-10.sql @@ -0,0 +1,13 @@ +-- Listing 6-10. Using the GEOCODE Function with aValid House Number +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('1350 Clay', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-11.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-11.sql new file mode 100644 index 0000000..848e35d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-11.sql @@ -0,0 +1,13 @@ +-- Listing 6-11. Using the GEOCODE Function with an Invalid House Number +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('4500 Clay Street', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-12.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-12.sql new file mode 100644 index 0000000..5a496d6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-12.sql @@ -0,0 +1,13 @@ +-- Listing 6-12. Using the GEOCODE Function with an Invalid Postal Code +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('1350 Clay St', 'San Francisco, CA 99130'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-13.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-13.sql new file mode 100644 index 0000000..f010379 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-13.sql @@ -0,0 +1,13 @@ +-- Listing 6-13. Using the GEOCODE Function with an Invalid Postal Code (in EXACTMode) +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('1350 Clay St', 'San Francisco, CA 99130'), + 'US', + 'EXACT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-14.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-14.sql new file mode 100644 index 0000000..1954651 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-14.sql @@ -0,0 +1,13 @@ +-- Listing 6-14. Using the GEOCODE Function to Find a POI +SET SERVEROUTPUT ON +BEGIN + FORMAT_GEO_ADDR ( + SDO_GCDR.GEOCODE ( + 'SPATIAL', + SDO_KEYWORDARRAY('Transamerica Pyramid', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-15.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-15.sql new file mode 100644 index 0000000..a4d128b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-15.sql @@ -0,0 +1,16 @@ +-- Listing 6-15. FORMAT_ADDR_ARRAY Procedure +CREATE OR REPLACE PROCEDURE format_addr_array +( + address_list SDO_ADDR_ARRAY +) +AS +BEGIN + IF address_list.count() > 0 THEN + FOR i IN 1..address_list.count() LOOP + dbms_output.put_line ('ADDRESS['||i||']'); + format_geo_addr (address_list(i)); + END LOOP; + END IF; +END; +/ +show errors diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-16.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-16.sql new file mode 100644 index 0000000..c7a8792 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-16.sql @@ -0,0 +1,13 @@ +-- Listing 6-16. Using GEOCODE_ALL over an Ambiguous Address +SET SERVEROUTPUT ON SIZE 32000 +BEGIN + FORMAT_ADDR_ARRAY ( + SDO_GCDR.GEOCODE_ALL ( + 'SPATIAL', + SDO_KEYWORDARRAY('12 Presidio', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-17.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-17.sql new file mode 100644 index 0000000..4b8e1a9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-17.sql @@ -0,0 +1,13 @@ +-- Listing 6-17. Using GEOCODE_ALL over an Ambiguous Address +SET SERVEROUTPUT ON SIZE 10000 +BEGIN + FORMAT_ADDR_ARRAY ( + SDO_GCDR.GEOCODE_ALL ( + 'SPATIAL', + SDO_KEYWORDARRAY('YMCA', 'San Francisco, CA'), + 'US', + 'DEFAULT' + ) +); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-18.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-18.sql new file mode 100644 index 0000000..ce71400 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-18.sql @@ -0,0 +1,4 @@ +-- Listing 6-18. Adding a Spatial Column +ALTER TABLE customers ADD (location SDO_GEOMETRY); +ALTER TABLE branches ADD (location SDO_GEOMETRY); +ALTER TABLE competitors ADD (location SDO_GEOMETRY); diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-19.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-19.sql new file mode 100644 index 0000000..0c47821 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-19.sql @@ -0,0 +1,11 @@ +-- Listing 6-19. Populating the location Column of the branches Table +UPDATE branches +SET location = SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY + ( street_number || ' ' || street_name, city || ' ' || state || ' ' + || postal_code), + 'US' +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-20.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-20.sql new file mode 100644 index 0000000..4cf2212 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-20.sql @@ -0,0 +1,10 @@ +-- Listing 6-20. Populating the location Column of the branches Table for German Addresses +UPDATE branches +SET location = SDO_GCDR.GEOCODE_AS_GEOMETRY +( + 'SPATIAL', + SDO_KEYWORDARRAY + ( street_name || ' ' || street_number || postal_code || ' ' || city), + 'DE' +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-21.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-21.sql new file mode 100644 index 0000000..ae3aa29 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-21.sql @@ -0,0 +1,122 @@ +-- Listing 6-21. Address Geocoding and Correction +SET SERVEROUTPUT ON SIZE 32000 +DECLARE + type match_counts_t is table of number; + + geo_addresses sdo_addr_array; -- Array of maching geocoded addresses + geo_address sdo_geo_addr; -- Matching address + geo_location sdo_geometry; -- Geographical location + + address_count number; -- Addresses processed + geocoded_count number; -- Addresses successfully geocoded + corrected_count number; -- Addresses geocoded and corrected + ambiguous_count number; -- Ambiguous addresses (multiple matches) + error_count number; -- Addresses rejected + + match_counts match_counts_t -- Counts per matchcode + := match_counts_t(); + + update_address boolean; -- Should update address ? + +BEGIN + + -- Clear counters + address_count := 0; + geocoded_count := 0; + error_count := 0; + corrected_count := 0; + ambiguous_count := 0; + match_counts.extend(20); + for i in 1..match_counts.count loop + match_counts(i) := 0; + end loop; + + -- Range over the customers + for b in + (select * from customers) + loop + + -- Geocode the address + geo_addresses := sdo_gcdr.geocode_all ( + 'SPATIAL', + SDO_KEYWORDARRAY ( + b.street_number || ' ' || b.street_name, + b.city || ' ' || b.postal_code), + 'US', + 'DEFAULT' + ); + + -- Check results + address_count := address_count + 1; + + if geo_addresses.count() > 1 then + + -- Address is ambiguous: reject + geo_location := NULL; + ambiguous_count := ambiguous_count + 1; + + else + -- Extract first or only match + geo_address := geo_addresses(1); + + -- Keep counts of matchcodes seen + match_counts(geo_address.matchcode) := + match_counts(geo_address.matchcode) + 1; + + -- The following matchcodes are accepted: + -- 1 = exact match + -- 2 = only street type or suffix/prefix is incorrect + -- 10 = only postal code is incorrect + if geo_address.matchcode in (1,2,10) then + -- Geocoding succeeded: construct geometric point + geo_location := sdo_geometry (2001, 8307, sdo_point_type ( + geo_address.longitude, geo_address.latitude, null), + null, null); + geocoded_count := geocoded_count + 1; + + -- If wrong street type or postal code (matchcodes 2 or 10) + -- accept the geocode and correct the address in the database + if geo_address.matchcode <> 1 then + update_address := true; + corrected_count := corrected_count + 1; + end if; + + else + -- For all other matchcoded, reject the geocode + error_count := error_count + 1; + geo_location := NULL; + end if; + + end if; + + -- Update location and corrected address in database + if update_address then + update customers + set location = geo_location, + street_name = geo_address.streetname, + postal_code = geo_address.postalcode + where id = b.id; + else + update customers + set location = geo_location + where id = b.id; + end if; + + end loop; + + -- Display counts of records processed + dbms_output.put_line ('Geocoding completed'); + dbms_output.put_line (address_count || ' Addresses processed'); + dbms_output.put_line (geocoded_count || ' Addresses successfully geocoded'); + dbms_output.put_line (corrected_count || ' Addresses corrected'); + dbms_output.put_line (ambiguous_count || ' ambiguous addresses rejected'); + dbms_output.put_line (error_count || ' addresses with errors'); + + for i in 1..match_counts.count loop + if match_counts(i) > 0 then + dbms_output.put_line ('Match code '|| i || ': ' || match_counts(i)); + end if; + end loop; + +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-22.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-22.sql new file mode 100644 index 0000000..18c838a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-22.sql @@ -0,0 +1,18 @@ +-- Listing 6-22. Automatic Geocoding of the branches Table Using a Simple Trigger +CREATE OR REPLACE TRIGGER branches_geocode + BEFORE INSERT OR UPDATE OF street_name, street_number, postal_code, city + ON branches + FOR EACH ROW +DECLARE + geo_location SDO_GEOMETRY; +BEGIN + geo_location := SDO_GCDR.GEOCODE_AS_GEOMETRY ( + 'SPATIAL', + SDO_KEYWORDARRAY ( + :new.street_number || ' ' || :new.street_name, + :new.city || ' ' || :new.postal_code), + 'US' + ); + :new.location := geo_location; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-06/listing-06-23.sql b/ProOracleSpatialCode/Code/Chapter-06/listing-06-23.sql new file mode 100644 index 0000000..7f8089b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-06/listing-06-23.sql @@ -0,0 +1,57 @@ +-- Listing 6-23. Automatic Geocoding with Address Correction +CREATE OR REPLACE TRIGGER branches_geocode + BEFORE INSERT OR UPDATE OF street_name, street_number, postal_code, city ON branches + FOR EACH ROW + +DECLARE + geo_location SDO_GEOMETRY; + geo_addresses SDO_ADDR_ARRAY; + geo_address SDO_GEO_ADDR; + update_address BOOLEAN; + +BEGIN + -- Geocode the address + geo_addresses := sdo_gcdr.geocode_all ( + 'SPATIAL', + SDO_KEYWORDARRAY ( + :new.street_number || ' ' || :new.street_name, + :new.city || ' ' || :new.postal_code), + 'US', + 'DEFAULT' + ); + + -- Check results + if geo_addresses.count() > 1 then + -- Address is ambiguous: reject + geo_location := NULL; + else + -- Extract first or only match + geo_address := geo_addresses(1); + -- The following matchcodes are accepted: + -- 1 = exact match + -- 2 = only street type or suffix/prefix is incorrect + -- 10 = only postal code is incorrect + if geo_address.matchcode in (1,2,10) then + -- Geocoding succeeded: construct geometric point + geo_location := sdo_geometry (2001, 8307, sdo_point_type ( + geo_address.longitude, geo_address.latitude, null), + null, null); + -- If wrong street type or postal code (matchcodes 2 or 10) + -- accept the geocode and correct the address in the database + if geo_address.matchcode <> 1 then + update_address := true; + end if; + else + -- For all other matchcoded, reject the geocode + geo_location := NULL; + end if; + end if; + + -- Update loaction + :new.location := geo_location; + -- If needed, correct address + :new.street_name := geo_address.streetname; + :new.postal_code := geo_address.postalcode; + +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/SdoLoad.java b/ProOracleSpatialCode/Code/Chapter-07/SdoLoad.java new file mode 100644 index 0000000..e149b59 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/SdoLoad.java @@ -0,0 +1,188 @@ +/* + * @(#)SdoLoad.java 1.0 12-Jul-2003 + * + * This program reads a geometry from an ascii text file, and inserts + * it in a database table. + * + * It uses the Java API for Oracle Spatial supplied with + * version 10.1 or the Oracle Server (class JGeometry) + * + * The program lets you specify connection parameters to a database, as + * well as the name of the table and the name of the geometry column to + * load into. It also lets you specify the name of an identification + * column (a number) to identify the row to insert or update. + * + * The input file is structured as described in the Region class + * + */ + +import java.io.*; +import java.sql.*; +import java.util.*; +import java.awt.geom.*; +import oracle.jdbc.driver.*; +import oracle.sql.STRUCT; +import oracle.spatial.geometry.JGeometry; + +public final class SdoLoad +{ + public static void main(String args[]) throws Exception + { + System.out.println ("SdoLoad - Oracle Spatial (SDO) load example"); + + // Check and process command line arguments + if (args.length != 9) { + System.out.println ("Parameters:"); + System.out.println (": JDBC connection string"); + System.out.println (" e.g: jdbc:oracle:thin:@server:port:sid"); + System.out.println (": User name"); + System.out.println (": User password"); + System.out.println (": Table to import"); + System.out.println (": Name of geometry colum"); + System.out.println (": Name of geometry id colum"); + System.out.println (": Value of geometry ID"); + System.out.println (": Name of input file"); + System.out.println (": I for insert or U for pdate"); + return; + } + String connectionString = args[0]; + String userName = args[1]; + String userPassword = args[2]; + String tableName = args[3]; + String geoColumn = args[4]; + String idColumn = args[5]; + int idValue = Integer.parseInt(args[6]); + String inputFileName = args[7]; + boolean insertAction = (args[8].compareTo("I")==0 ? true : false); + + // Open input file + System.out.println ("Opening file '" + inputFileName + "'"); + BufferedReader inputFile = + new BufferedReader(new FileReader(inputFileName)); + + // Register the Oracle JDBC driver + DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); + + // Get a connection to the database + System.out.println ("Connecting to database '"+connectionString+"'"); + Connection dbConnection = DriverManager.getConnection(connectionString, userName, userPassword); + + // Load the geometry from the file + loadGeometry(dbConnection, tableName, geoColumn, idColumn, idValue, inputFile, insertAction); + + // Close database connection + dbConnection.close(); + + // Close input file + inputFile.close(); + } + + static void loadGeometry(Connection dbConnection, String tableName, + String geoColumn, String idColumn, int idValue, BufferedReader inputFile, + boolean insertAction) + throws SQLException, IOException + { + // Construct the SQL statement + String SqlStatement; + if (insertAction) + SqlStatement = "INSERT INTO " + tableName + " (" + geoColumn + "," + idColumn + ") " + + "VALUES (?, ?)"; + else + SqlStatement = "UPDATE " + tableName + " SET " + geoColumn + " = ? " + + "WHERE " + idColumn + " = ?"; + System.out.println ("Executing query: '"+SqlStatement+"'"); + + // Prepare the SQL statement + PreparedStatement stmt = dbConnection.prepareStatement(SqlStatement); + + // Load geomety Region from input file + Region polygon = new Region(inputFile); + System.out.println ("Region geometry loaded (" + + polygon.getNrOfPoints() + " points)"); + + // Get the list of points of the region + double ordinates[] = polygon.getOrdinates(); + + // Construct new JGeometry object + JGeometry geom = JGeometry.createLinearPolygon(ordinates, 2, 8307); + + // Convert object into java STRUCT + STRUCT dbObject = JGeometry.store (geom, dbConnection); + + // Insert or update row in the database table + stmt.setObject (1,dbObject); + stmt.setInt (2, idValue); + stmt.execute(); + + stmt.close(); + } + + + /* Class Region + + This class defines the geometry of a region as obtained from + an ascii file. + + The input is a list of records: + + NUM_POINTS 26 + POINT 1 -77.120201 38.9342 + POINT 2 -77.101501 38.910999 + ...... + POINT 26 -77.120201 38.9342 + + The first line defines the number of points that follow. + Then each point is defined on a separate line. + + The program performs minimal parsing and validation of the + input file. + */ + static class Region { + + int nrOfPoints = 0; + Point2D points[] = null; + + public Region(BufferedReader inputFile) + throws IOException { + this.loadFromFile (inputFile); + } + + public void loadFromFile (BufferedReader inputFile) + throws IOException { + + String s; + while((s = inputFile.readLine())!= null) { + StringTokenizer st = new StringTokenizer (s); + int n = st.countTokens(); + if (n > 0) { + String tk = st.nextToken(); + if (tk.compareTo ("NUM_POINTS") == 0) { + nrOfPoints = Integer.parseInt(st.nextToken()); + points = new Point2D[nrOfPoints]; + } + if (tk.compareTo ("POINT") == 0) { + int pn = Integer.parseInt(st.nextToken()); + double x = Double.parseDouble(st.nextToken()); + double y = Double.parseDouble(st.nextToken()); + points[pn-1] = new Point2D.Double(x,y); + } + } + } + } + public Point2D[] getPoints() { + return points; + } + public double[] getOrdinates() { + double ordinates[] = new double[nrOfPoints * 2]; + for (int i=0; i: JDBC connection string"); + System.out.println (" e.g: jdbc:oracle:thin:@server:port:sid"); + System.out.println (": User name"); + System.out.println (": User password"); + System.out.println ("
: Table to unload"); + System.out.println (": Name of geometry colum,"); + System.out.println (": WHERE clause"); + System.out.println (": 0=none, 1=raw, 2=format"); + return; + } + + String connectionString = args[0]; + String userName = args[1]; + String userPassword = args[2]; + String tableName = args[3]; + String geoColumn = args[4]; + String predicate = args[5]; + int printStyle = Integer.parseInt(args[6]); + + // Register the Oracle JDBC driver + DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); + + // Get a connection to the database + System.out.println ("Connecting to database '"+connectionString+"'"); + Connection dbConnection = DriverManager.getConnection(connectionString, + userName, userPassword); + System.out.println ("Got a connection: "+dbConnection.getClass().getName()); + + // Perform the database query + printGeometries(dbConnection, tableName, geoColumn, predicate, printStyle); + + // Close database connection + dbConnection.close(); + } + + static void printGeometries(Connection dbConnection, String tableName, + String geoColumn, String predicate,int printStyle) + throws Exception + { + long totalPoints = 0; + long totalSize = 0; + JGeometry geom; + + // Construct SQL query + String sqlQuery = "SELECT " + geoColumn + " FROM " + tableName + " " + + predicate; + System.out.println ("Executing query: '"+sqlQuery+"'"); + + // Execute query + Statement stmt = dbConnection.createStatement(); + OracleResultSet ors = (OracleResultSet) stmt.executeQuery(sqlQuery); + + // Process results + int rowNumber = 0; + while (ors.next()) + { + ++rowNumber; + + // Extract JDBC object from record into structure + STRUCT dbObject = (STRUCT) ors.getObject(1); + + // Import from structure into Geometry object + geom = JGeometry.load(dbObject); + + // extract details from jGeometry object + int gType = geom.getType(); + int gSRID = geom.getSRID(); + int gDimensions = geom.getDimensions(); + long gNumPoints = geom.getNumPoints(); + long gSize = geom.getSize(); + boolean isPoint = geom.isPoint(); + boolean isCircle = geom.isCircle(); + boolean hasCircularArcs = geom.hasCircularArcs(); + boolean isGeodeticMBR = geom.isGeodeticMBR(); + boolean isLRSGeometry = geom.isLRSGeometry(); + boolean isMultiPoint = geom.isMultiPoint(); + boolean isRectangle = geom.isRectangle(); + + // point + double gPoint[] = geom.getPoint(); + // element info array + int gElemInfo[] = geom.getElemInfo(); + int gNumElements = (gElemInfo == null ? 0 : gElemInfo.length / 3); + // ordinates array + double gOrdinates[] = geom.getOrdinatesArray(); + + // other information + double[] gFirstPoint = geom.getFirstPoint(); + double[] gLastPoint = geom.getLastPoint(); + Point2D gLabelPoint = geom.getLabelPoint(); + Point2D gJavaPoint = geom.getJavaPoint(); + Point2D[] gJavaPoints = (isMultiPoint ? geom.getJavaPoints():null); + double[] gMBR = geom.getMBR(); + Shape gShape = geom.createShape(); + + totalSize += gSize; + totalPoints += gNumPoints; + + if (printStyle > 0) + System.out.println ("Geometry # " + rowNumber + ":"); + + // Print out geometry in SDO_GEOMETRY format + if ((printStyle & 1) == 1 ) + System.out.println (printGeom(geom)); + + // Print out formatted geometry + if ((printStyle & 2) == 2) { + System.out.println (" Type: " + gType); + System.out.println (" SRID: " + gSRID); + System.out.println (" Dimensions: " + gDimensions); + System.out.println (" NumPoints: " + gNumPoints); + System.out.println (" Size: " + gSize); + System.out.println (" isPoint: " + isPoint); + System.out.println (" isCircle: " + isCircle); + System.out.println (" hasCircularArcs: " + hasCircularArcs); + System.out.println (" isGeodeticMBR: " + isGeodeticMBR); + System.out.println (" isLRSGeometry: " + isLRSGeometry); + System.out.println (" isMultiPoint: " + isMultiPoint); + System.out.println (" isRectangle: " + isRectangle); + System.out.println (" MBR: (" + + gMBR[0] + " " + gMBR[1] + ") (" + gMBR[2] + " " + gMBR[3] + ") "); + System.out.println (" First Point: " + printPoint(gFirstPoint)); + System.out.println (" Last Point: " + printPoint(gLastPoint)); + System.out.println (" Label Point: " + printPoint(gLabelPoint)); + System.out.println (" Point: " + printPoint(gPoint)); + System.out.println (" Java Point: " + printPoint(gJavaPoint)); + System.out.println (" Java Points List: " + + (gJavaPoints==null ? "NULL": "["+gJavaPoints.length+"]")); + if (gJavaPoints != null) + for (int i=0; i new_long, + Y=> new_lat, + SRID=> 8307 + ) ; + + -- Compute sales region for this branch + sales_region := + rectangle + ( + CTR_X=> new_long, + CTR_Y=> new_lat, + EXP_X=> 0.005, + EXP_Y=> 0.0025, + SRID=> 8307 + ) ; + + -- Create Delivery Route + route := + line + ( + FIRST_X=> -122.4804, + FIRST_Y=> 37.7805222, + NEXT_X=> -123, + NEXT_Y=> 38, + SRID=> 8307 + ) ; + + -- Update Delivery Route by adding new point + route := + add_to_line + ( + GEOM=> route, + POINT => POINT(-124, 39, 8307) + ) ; + + -- Perform additional analysis such as length of route, + -- or # of customers in sales region (we will see examples in Chapters 8 and 9) + -- ... + -- Update geometry in branches table + UPDATE branches SET LOCATION = new_branch_loc WHERE id=1; + +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-04.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-04.sql new file mode 100644 index 0000000..a4229dc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-04.sql @@ -0,0 +1,87 @@ +-- Listing 7-4. Manipulating VARRAYs +SET SERVEROUTPUT ON +DECLARE + + -- Declare a type for the VARRAT + TYPE MY_ARRAY_TYPE IS VARRAY(10) OF NUMBER; + + -- Declare a varray variable + V MY_ARRAY_TYPE; + + -- Other variables + I NUMBER; + K NUMBER; + L NUMBER; + ARRAY_CAPACITY NUMBER; + N_ENTRIES NUMBER; + +BEGIN + -- Initialize the array + V := MY_ARRAY_TYPE (1,2,3,4); + + -- Get the value of a specific entry + DBMS_OUTPUT.PUT_LINE('* Values for specific array entries'); + K := V(3); + DBMS_OUTPUT.PUT_LINE('V(3)='|| V(3)); + I := 2; + L := V(I+1); + DBMS_OUTPUT.PUT_LINE('I=' || I); + DBMS_OUTPUT.PUT_LINE('V(I+1)=' || V(I+1)); + + -- Find the capacity of a VARRAY: + DBMS_OUTPUT.PUT_LINE('* Array capacity'); + ARRAY_CAPACITY := V.LIMIT(); + DBMS_OUTPUT.PUT_LINE('Array Capacity: V.LIMIT()='||V.LIMIT()); + N_ENTRIES := V.COUNT(); + DBMS_OUTPUT.PUT_LINE('Current Array Size: V.COUNT()='||V.COUNT()); + + -- Range over all values in a VARRAY + DBMS_OUTPUT.PUT_LINE('* Array Content'); + FOR I IN 1..V.COUNT() LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V(I)); + END LOOP; + + FOR I IN V.FIRST()..V.LAST() LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V(I)); + END LOOP; + + I := V.COUNT(); + WHILE I IS NOT NULL LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V(I)); + I := V.PRIOR(I); + END LOOP; + + -- Extend the VARRAY + DBMS_OUTPUT.PUT_LINE('* Extend the array'); + I := V.LAST(); + V.EXTEND(2); + V(I+1) := 5; + V(I+2) := 6; + + DBMS_OUTPUT.PUT_LINE('Array Capacity: V.LIMIT()='||V.LIMIT()); + DBMS_OUTPUT.PUT_LINE('Current Array Size: V.COUNT()='||V.COUNT()); + FOR I IN 1..V.COUNT() LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')='|| V(I)); + END LOOP; + + -- Shrink the VARRAY + DBMS_OUTPUT.PUT_LINE('* Trim the array'); + V.TRIM(); + + DBMS_OUTPUT.PUT_LINE('Array Capacity: V.LIMIT()='||V.LIMIT()); + DBMS_OUTPUT.PUT_LINE('Current Array Size: V.COUNT()='||V.COUNT()); + FOR I IN 1..V.COUNT() LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')='|| V(I)); + END LOOP; + + -- Delete all entries from the VARRAY + DBMS_OUTPUT.PUT_LINE('* Empty the array'); + V.DELETE(); + + DBMS_OUTPUT.PUT_LINE('Array Capacity: V.LIMIT()='||V.LIMIT()); + DBMS_OUTPUT.PUT_LINE('Current Array Size: V.COUNT()='||V.COUNT()); + FOR I IN 1..V.COUNT() LOOP + DBMS_OUTPUT.PUT_LINE('V('||I||')='|| V(I)); + END LOOP; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-05.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-05.sql new file mode 100644 index 0000000..5cb6e66 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-05.sql @@ -0,0 +1,11 @@ +-- Listing 7-5. Point Constructor Function +CREATE OR REPLACE FUNCTION point ( + x NUMBER, y NUMBER, srid NUMBER DEFAULT 8307) +RETURN SDO_GEOMETRY +DETERMINISTIC +IS +BEGIN + RETURN SDO_GEOMETRY ( + 2001, srid, SDO_POINT_TYPE (x,y,NULL), NULL, NULL); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-06.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-06.sql new file mode 100644 index 0000000..10bfb64 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-06.sql @@ -0,0 +1,17 @@ +-- Listing 7-6. Rectangle Constructor +CREATE OR REPLACE FUNCTION rectangle ( + ctr_x NUMBER, ctr_y NUMBER, exp_x NUMBER, exp_y NUMBER, srid NUMBER) +RETURN SDO_GEOMETRY +DETERMINISTIC +IS + r SDO_GEOMETRY; +BEGIN + r := SDO_GEOMETRY ( + 2003, srid, NULL, + SDO_ELEM_INFO_ARRAY (1, 1003, 3), + SDO_ORDINATE_ARRAY ( + ctr_x - exp_x, ctr_y - exp_y, + ctr_x + exp_x, ctr_y + exp_y)); + RETURN r; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-07.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-07.sql new file mode 100644 index 0000000..072e889 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-07.sql @@ -0,0 +1,17 @@ +-- Listing 7-7. Line Constructor +CREATE OR REPLACE FUNCTION line ( + first_x NUMBER, first_y NUMBER, next_x NUMBER, next_y NUMBER, srid NUMBER) +RETURN SDO_GEOMETRY +DETERMINISTIC +IS + l SDO_GEOMETRY; +BEGIN + l := SDO_GEOMETRY ( + 2002, srid, NULL, + SDO_ELEM_INFO_ARRAY (1, 2, 1), + SDO_ORDINATE_ARRAY ( + first_x, first_y, + next_x, next_y)); + RETURN l; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-08.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-08.sql new file mode 100644 index 0000000..b02faa2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-08.sql @@ -0,0 +1,9 @@ +-- Listing 7-8. Counting the Number of Points in a Geometry +CREATE OR REPLACE FUNCTION get_num_points ( + g SDO_GEOMETRY) +RETURN NUMBER +IS +BEGIN + RETURN g.SDO_ORDINATES.COUNT() / SUBSTR(g.SDO_GTYPE,1,1); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-09.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-09.sql new file mode 100644 index 0000000..018d320 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-09.sql @@ -0,0 +1,37 @@ +-- Listing 7-9. Function to Extract a Point from a Geometry +CREATE OR REPLACE FUNCTION get_point ( + geom SDO_GEOMETRY, point_number NUMBER DEFAULT 1 +) RETURN SDO_GEOMETRY +IS + g SDO_GEOMETRY; -- Updated Geometry + d NUMBER; -- Number of dimensions in geometry + p NUMBER; -- Index into ordinates array + px NUMBER; -- X of extracted point + py NUMBER; -- Y of extracted point + +BEGIN + -- Get the number of dimensions from the gtype + d := SUBSTR (geom.SDO_GTYPE, 1, 1); + + -- Verify that the point exists + IF point_number < 1 + OR point_number > geom.SDO_ORDINATES.COUNT()/d THEN + RETURN NULL; + END IF; + + -- Get index in ordinates array + p := (point_number-1) * d + 1; + + -- Extract the X and Y coordinates of the desired point + px := geom.SDO_ORDINATES(p); + py := geom.SDO_ORDINATES(p+1); + + -- Construct and return the point + RETURN + SDO_GEOMETRY ( + 2001, + geom.SDO_SRID, + SDO_POINT_TYPE (px, py, NULL), + NULL, NULL); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-10.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-10.sql new file mode 100644 index 0000000..6bf633e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-10.sql @@ -0,0 +1,16 @@ +-- Listing 7-10. Getting the First,Middle, and Last Points of a Line String + +-- Getting the first point of a line string +SELECT get_point(geom) p +FROM us_interstates +WHERE interstate='I95'; + +-- Getting the last point of a line string +SELECT get_point(geom, get_num_points(geom)) p +FROM us_interstates +WHERE interstate='I95'; + +-- Getting the middle point of a line string +SELECT get_point(geom, ROUND(get_num_points(geom)/2)) p +FROM us_interstates +WHERE interstate='I95'; diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-11.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-11.sql new file mode 100644 index 0000000..3f1b58d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-11.sql @@ -0,0 +1,42 @@ +-- Listing 7-11. remove_point Function +CREATE OR REPLACE FUNCTION remove_point ( + geom SDO_GEOMETRY, point_number NUMBER +) RETURN SDO_GEOMETRY +IS + g MDSYS.SDO_GEOMETRY; -- Updated Geometry + d NUMBER; -- Number of dimensions in geometry + p NUMBER; -- Index into ordinates array + i NUMBER; -- Index into ordinates array + +BEGIN + -- Get the number of dimensions from the gtype + d := SUBSTR (geom.SDO_GTYPE, 1, 1); + + -- Get index in ordinates array + -- If 0 then we want the last point + IF point_number = 0 THEN + p := geom.SDO_ORDINATES.COUNT() - d + 1; + ELSE + p := (point_number-1) * d + 1; + END IF; + + -- Verify that the point exists + IF p > geom.SDO_ORDINATES.COUNT() THEN + RETURN NULL; + END IF; + + -- Initialize output line with input line + g := geom; + + -- Step 1: Shift the ordinates "up" + FOR i IN p..g.SDO_ORDINATES.COUNT()-d LOOP + g.SDO_ORDINATES(i) := g.SDO_ORDINATES(i+d); + END LOOP; + + -- Step 2: Trim the ordinates array + g.SDO_ORDINATES.TRIM (d); + + -- Return the updated geometry + RETURN g; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-12.sql b/ProOracleSpatialCode/Code/Chapter-07/listing-07-12.sql new file mode 100644 index 0000000..b3a36aa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-12.sql @@ -0,0 +1,55 @@ +-- Listing 7-12. Adding a Point in a Line String (add_to_line in Listing 7-3) +CREATE OR REPLACE FUNCTION add_to_line ( + geom SDO_GEOMETRY, + point SDO_GEOMETRY, + point_number NUMBER DEFAULT 0 +) RETURN SDO_GEOMETRY +IS + g SDO_GEOMETRY; -- Updated geometry + d NUMBER; -- Number of dimensions in line geometry + t NUMBER; -- Geometry type + p NUMBER; -- Insertion point into ordinates array + i NUMBER; + +BEGIN + -- Get the number of dimensions from the gtype + d := SUBSTR (geom.SDO_GTYPE, 1, 1); + + -- Get index in ordinates array + -- If 0, then we want the last point + IF point_number = 0 THEN + p := geom.SDO_ORDINATES.COUNT() + 1; + ELSE + p := (point_number-1) * d + 1; + END IF; + + -- Verify that the insertion point exists + IF point_number <> 0 THEN + IF p > geom.SDO_ORDINATES.LAST() + OR p < geom.SDO_ORDINATES.FIRST() THEN + RAISE_APPLICATION_ERROR (-20000, 'Invalid insertion point'); + END IF; + END IF; + + -- Initialize output line with input line + g := geom; + + -- Step 1: Extend the ordinates array + g.SDO_ORDINATES.EXTEND(d); + + -- Step 2: Shift the ordinates "down". + FOR i IN REVERSE p..g.SDO_ORDINATES.COUNT()-d LOOP + g.SDO_ORDINATES(i+d) := g.SDO_ORDINATES(i); + END LOOP; + + -- Step 3: Store the new point + g.SDO_ORDINATES(p) := point.SDO_POINT.X; + g.SDO_ORDINATES(p+1) := point.SDO_POINT.Y; + IF d = 3 THEN + g.SDO_ORDINATES(p+2) := point.SDO_POINT.Z; + END IF; + + -- Return the new line string + RETURN g; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-07/listing-07-13.java b/ProOracleSpatialCode/Code/Chapter-07/listing-07-13.java new file mode 100644 index 0000000..703b121 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/listing-07-13.java @@ -0,0 +1,298 @@ +/* + * @(#)SdoPrint.java 1.0 12-Jul-2003 + * + * This program uses the Java API for Oracle Spatial supplied with + * version 10.1 of the Oracle Server (class JGeometry) + * + * It illustrates the use of Geometry to extract and process geometry + * objects stored in tables inside the Oracle database using the + * SDO_GEOMETRY object type. + * + * The program lets you specify connection parameters to a database, as + * well as the name of a table and the name of a geometry column to + * process. You can optionally specify a predicate (a WHERE clause) to select + * the rows to fetch. + * + * Finally you can choose the way the geometries will be formatted: + * + * 0 = no output. + * 1 = format as an SDO_GEOMETRY constructor (similar to SQLPLUS output) + * 2 = display the results from each getXxx() and isXxx() methods of the + * Geometry objects + * + * You can combine the settings. For example, 3 shows both formats. + * + * The program also times the individual steps needed to process a geometry, + * and displays the total time elapsed for each step: + * + * - Getting object = time needed to perform the getObject() method, which + * extracts the object from the result set and returns an oracle.sql.STRUCT. + * - Converting geometry = time to convert the STRUCT into a Geometry object. + * - Extracting information = time to extract information from the Geometry + * object into regular Java variables. + */ + +import java.io.*; +import java.sql.*; +import java.util.*; +import java.awt.geom.*; +import java.awt.Shape; +import oracle.jdbc.driver.*; +import oracle.sql.*; +import oracle.spatial.geometry.*; + +public final class SdoPrint +{ + public static void main(String args[]) throws Exception + { + System.out.println ("SdoPrint - Oracle Spatial (SDO) read"); + + // Check and process command line arguments + if (args.length != 7) { + System.out.println ("Parameters:"); + System.out.println (": JDBC connection string"); + System.out.println (" e.g: jdbc:oracle:thin:@server:port:sid"); + System.out.println (": User name"); + System.out.println (": User password"); + System.out.println ("
: Table to unload"); + System.out.println (": Name of geometry colum,"); + System.out.println (": WHERE clause"); + System.out.println (": 0=none, 1=raw, 2=format"); + return; + } + + String connectionString = args[0]; + String userName = args[1]; + String userPassword = args[2]; + String tableName = args[3]; + String geoColumn = args[4]; + String predicate = args[5]; + int printStyle = Integer.parseInt(args[6]); + + // Register the Oracle JDBC driver + DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); + + // Get a connection to the database + System.out.println ("Connecting to database '"+connectionString+"'"); + Connection dbConnection = DriverManager.getConnection(connectionString, + userName, userPassword); + System.out.println ("Got a connection: "+dbConnection.getClass().getName()); + + // Perform the database query + printGeometries(dbConnection, tableName, geoColumn, predicate, printStyle); + + // Close database connection + dbConnection.close(); + } + + static void printGeometries(Connection dbConnection, String tableName, + String geoColumn, String predicate,int printStyle) + throws Exception + { + long totalPoints = 0; + long totalSize = 0; + JGeometry geom; + + // Construct SQL query + String sqlQuery = "SELECT " + geoColumn + " FROM " + tableName + " " + + predicate; + System.out.println ("Executing query: '"+sqlQuery+"'"); + + // Execute query + Statement stmt = dbConnection.createStatement(); + OracleResultSet ors = (OracleResultSet) stmt.executeQuery(sqlQuery); + + // Process results + int rowNumber = 0; + while (ors.next()) + { + ++rowNumber; + + // Extract JDBC object from record into structure + STRUCT dbObject = (STRUCT) ors.getObject(1); + + // Import from structure into Geometry object + geom = JGeometry.load(dbObject); + + // extract details from jGeometry object + int gType = geom.getType(); + int gSRID = geom.getSRID(); + int gDimensions = geom.getDimensions(); + long gNumPoints = geom.getNumPoints(); + long gSize = geom.getSize(); + boolean isPoint = geom.isPoint(); + boolean isCircle = geom.isCircle(); + boolean hasCircularArcs = geom.hasCircularArcs(); + boolean isGeodeticMBR = geom.isGeodeticMBR(); + boolean isLRSGeometry = geom.isLRSGeometry(); + boolean isMultiPoint = geom.isMultiPoint(); + boolean isRectangle = geom.isRectangle(); + + // point + double gPoint[] = geom.getPoint(); + // element info array + int gElemInfo[] = geom.getElemInfo(); + int gNumElements = (gElemInfo == null ? 0 : gElemInfo.length / 3); + // ordinates array + double gOrdinates[] = geom.getOrdinatesArray(); + + // other information + double[] gFirstPoint = geom.getFirstPoint(); + double[] gLastPoint = geom.getLastPoint(); + Point2D gLabelPoint = geom.getLabelPoint(); + Point2D gJavaPoint = geom.getJavaPoint(); + Point2D[] gJavaPoints = (isMultiPoint ? geom.getJavaPoints():null); + double[] gMBR = geom.getMBR(); + Shape gShape = geom.createShape(); + + totalSize += gSize; + totalPoints += gNumPoints; + + if (printStyle > 0) + System.out.println ("Geometry # " + rowNumber + ":"); + + // Print out geometry in SDO_GEOMETRY format + if ((printStyle & 1) == 1 ) + System.out.println (printGeom(geom)); + + // Print out formatted geometry + if ((printStyle & 2) == 2) { + System.out.println (" Type: " + gType); + System.out.println (" SRID: " + gSRID); + System.out.println (" Dimensions: " + gDimensions); + System.out.println (" NumPoints: " + gNumPoints); + System.out.println (" Size: " + gSize); + System.out.println (" isPoint: " + isPoint); + System.out.println (" isCircle: " + isCircle); + System.out.println (" hasCircularArcs: " + hasCircularArcs); + System.out.println (" isGeodeticMBR: " + isGeodeticMBR); + System.out.println (" isLRSGeometry: " + isLRSGeometry); + System.out.println (" isMultiPoint: " + isMultiPoint); + System.out.println (" isRectangle: " + isRectangle); + System.out.println (" MBR: (" + + gMBR[0] + " " + gMBR[1] + ") (" + gMBR[2] + " " + gMBR[3] + ") "); + System.out.println (" First Point: " + printPoint(gFirstPoint)); + System.out.println (" Last Point: " + printPoint(gLastPoint)); + System.out.println (" Label Point: " + printPoint(gLabelPoint)); + System.out.println (" Point: " + printPoint(gPoint)); + System.out.println (" Java Point: " + printPoint(gJavaPoint)); + System.out.println (" Java Points List: " + + (gJavaPoints==null ? "NULL": "["+gJavaPoints.length+"]")); + if (gJavaPoints != null) + for (int i=0; i: JDBC connection string"); + System.out.println (" e.g: jdbc:oracle:thin:@server:port:sid"); + System.out.println (": User name"); + System.out.println (": User password"); + System.out.println ("
: Table to import"); + System.out.println (": Name of geometry colum"); + System.out.println (": Name of geometry id colum"); + System.out.println (": Value of geometry ID"); + System.out.println (": Name of input file"); + System.out.println (": I for insert or U for pdate"); + return; + } + String connectionString = args[0]; + String userName = args[1]; + String userPassword = args[2]; + String tableName = args[3]; + String geoColumn = args[4]; + String idColumn = args[5]; + int idValue = Integer.parseInt(args[6]); + String inputFileName = args[7]; + boolean insertAction = (args[8].compareTo("I")==0 ? true : false); + + // Open input file + System.out.println ("Opening file '" + inputFileName + "'"); + BufferedReader inputFile = + new BufferedReader(new FileReader(inputFileName)); + + // Register the Oracle JDBC driver + DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); + + // Get a connection to the database + System.out.println ("Connecting to database '"+connectionString+"'"); + Connection dbConnection = DriverManager.getConnection(connectionString, userName, userPassword); + + // Load the geometry from the file + loadGeometry(dbConnection, tableName, geoColumn, idColumn, idValue, inputFile, insertAction); + + // Close database connection + dbConnection.close(); + + // Close input file + inputFile.close(); + } + + static void loadGeometry(Connection dbConnection, String tableName, + String geoColumn, String idColumn, int idValue, BufferedReader inputFile, + boolean insertAction) + throws SQLException, IOException + { + // Construct the SQL statement + String SqlStatement; + if (insertAction) + SqlStatement = "INSERT INTO " + tableName + " (" + geoColumn + "," + idColumn + ") " + + "VALUES (?, ?)"; + else + SqlStatement = "UPDATE " + tableName + " SET " + geoColumn + " = ? " + + "WHERE " + idColumn + " = ?"; + System.out.println ("Executing query: '"+SqlStatement+"'"); + + // Prepare the SQL statement + PreparedStatement stmt = dbConnection.prepareStatement(SqlStatement); + + // Load geomety Region from input file + Region polygon = new Region(inputFile); + System.out.println ("Region geometry loaded (" + + polygon.getNrOfPoints() + " points)"); + + // Get the list of points of the region + double ordinates[] = polygon.getOrdinates(); + + // Construct new JGeometry object + JGeometry geom = JGeometry.createLinearPolygon(ordinates, 2, 8307); + + // Convert object into java STRUCT + STRUCT dbObject = JGeometry.store (geom, dbConnection); + + // Insert or update row in the database table + stmt.setObject (1,dbObject); + stmt.setInt (2, idValue); + stmt.execute(); + + stmt.close(); + } + + + /* Class Region + + This class defines the geometry of a region as obtained from + an ascii file. + + The input is a list of records: + + NUM_POINTS 26 + POINT 1 -77.120201 38.9342 + POINT 2 -77.101501 38.910999 + ...... + POINT 26 -77.120201 38.9342 + + The first line defines the number of points that follow. + Then each point is defined on a separate line. + + The program performs minimal parsing and validation of the + input file. + */ + static class Region { + + int nrOfPoints = 0; + Point2D points[] = null; + + public Region(BufferedReader inputFile) + throws IOException { + this.loadFromFile (inputFile); + } + + public void loadFromFile (BufferedReader inputFile) + throws IOException { + + String s; + while((s = inputFile.readLine())!= null) { + StringTokenizer st = new StringTokenizer (s); + int n = st.countTokens(); + if (n > 0) { + String tk = st.nextToken(); + if (tk.compareTo ("NUM_POINTS") == 0) { + nrOfPoints = Integer.parseInt(st.nextToken()); + points = new Point2D[nrOfPoints]; + } + if (tk.compareTo ("POINT") == 0) { + int pn = Integer.parseInt(st.nextToken()); + double x = Double.parseDouble(st.nextToken()); + double y = Double.parseDouble(st.nextToken()); + points[pn-1] = new Point2D.Double(x,y); + } + } + } + } + public Point2D[] getPoints() { + return points; + } + public double[] getOrdinates() { + double ordinates[] = new double[nrOfPoints * 2]; + for (int i=0; i +#include +#include +#include +#include "sdo_geometry.h" + +#define use_array_interface 0 + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Types and structures +*******************************************************************************/ + +struct point { + double x; + double y; + double z; +}; +typedef struct point point_struct; + +struct geometry +{ + int gtype; + int srid; + struct point *point; + int n_elem_info; + int *elem_info; + int n_ordinates; + double *ordinates; +}; +typedef struct geometry geometry_struct; + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = -1; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "ERROR %d: %s\n", errcode, errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT+OCI_OBJECT), /* (in) Mode: handles objects */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: FreeGeometry +** +** Description: Frees the memory used for a geometry structure +*******************************************************************************/ +void FreeGeometry (geometry_struct *geometry) { + if (geometry != 0) { + /* Free memory used for the point structure */ + if (geometry->point != NULL) + free (geometry->point); + /* Free memory used for the elem_info vector */ + if (geometry->elem_info != 0) + free (geometry->elem_info); + /* Free memory used for the ordinates vector */ + if (geometry->ordinates != 0) + free (geometry->ordinates); + /* Free memory used for the geometry structure */ + free (geometry); + } +} + +/******************************************************************************* +** Routine: StoreGeometry +** +** Description: Stores a geometry from a C memory structure.into an SDO_GEOMETRY +** object structure +*******************************************************************************/ +SDO_GEOMETRY *StoreGeometry () +{ +} + +/******************************************************************************* +** Routine: ReadGeometryFromFile +** +** Description: Reads and parses a geometry from the input file +*******************************************************************************/ +geometry_struct* ReadGeometryFromFile ( + FILE *input_file + ) +{ + +} + +/******************************************************************************* +** Routine: LoadGeometries +** +** Description: Load all geometries from the input file +*******************************************************************************/ +void LoadGeometries ( + char *tablename, + char *id_column, + char *geo_column, + char *filename) +{ + int rows_loaded = 0; /* Row counter */ + char insert_statement[1024]; /* Buffer to build INSERT statement */ + OCIStmt *insert_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + FILE *input_file; + + /* Bind handles for input variables */ + OCIBind *id_hp = NULL; + OCIBind *geometry_hp = NULL; + + /* Input variables */ + long id; + SDO_GEOMETRY *geometry_obj = NULL; + SDO_GEOMETRY_ind *geometry_ind = NULL; + + /* Type descriptor for geometry object type */ + OCIType *geometry_type_desc; + + /* Host variables */ + geometry_struct *geometry; + + /* Open input file */ + input_file = fopen (filename, "r"); + if (input_file == NULL) { + printf ("Could not open file %s\n", filename); + exit (1); + } + + /* Construct the insert statement */ + sprintf (insert_statement, "insert into %s (%s, %s) values (:id, :geometry)", tablename, id_column, geo_column); + printf ("Executing :\nSQL> %s\n\n", insert_statement); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&insert_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + insert_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)insert_statement, /* (in) SQL statement */ + (ub4)strlen(insert_statement), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get type descriptor for geometry object type */ + status = OCITypeByName ( + (dvoid *)envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + svchp, /* (in) Service Context Handle */ + "MDSYS", /* (in) Type owner name */ + strlen("MDSYS"), /* (in) (length) */ + "SDO_GEOMETRY", /* (in) Type name */ + strlen("SDO_GEOMETRY"), /* (in) (length) */ + 0, /* (in) Version name (NOT USED) */ + 0, /* (in) (length) */ + OCI_DURATION_SESSION, /* (in) Pin duration */ + OCI_TYPEGET_HEADER , /* (in) Get option */ + &geometry_type_desc); /* (out) Type descriptor */ + + /* Bind the input variables */ + + /* ID (integer) */ + status = OCIBindByName( + insert_stmthp, /* (in) Statement Handle */ + &id_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":ID", /* (in) Placeholder */ + strlen(":ID"), /* (in) Placeholder length */ + (ub1 *) &id, /* (in) Value Pointer */ + sizeof(id), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* GEOMETRY (ADT) */ + status = OCIBindByName( + insert_stmthp, /* (in) Statement Handle */ + &geometry_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":GEOMETRY", /* (in) Placeholder */ + strlen(":GEOMETRY"), /* (in) Placeholder length */ + (ub1 *) 0, /* (in) Value Pointer (NOT USED) */ + 0, /* (in) Value Size (NOT USED) */ + SQLT_NTY, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + status = OCIBindObject( + geometry_hp, /* (in) Bind handle */ + errhp, /* (in) Error handle */ + geometry_type_desc, /* (in) Geometry type descriptor */ + (dvoid **) &geometry_obj, /* (in) Value Pointer */ + (ub4 *)0, /* (in) Value Size (NOT USED) */ + (dvoid **) &geometry_ind, /* (in) Indicator Pointer */ + (ub4 *)0 /* (in) Indicator Size */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + geometry = ReadGeometryFromFile(input_file); + while (geometry != NULL) + { + rows_loaded++; + + /* Store geometry from C structure into SDO_GEOMETRY OCI structure*/ + StoreGeometry (geometry, geometry_obj, geometry_ind); + + /* Execute insert statement */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + insert_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + /* Read next geometry */ + geometry = ReadGeometryFromFile(input_file); + } + printf ("\n%d rows loaded\n", rows_loaded); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)insert_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database, *tablename, *id_column, *geo_column, *filename; + + if( argc != 8) { + printf("USAGE: %s \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + tablename = argv[4]; + id_column = argv[5]; + geo_column = argv[6]; + filename = argv[7]; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + LoadGeometries(tablename, id_column, geo_column, filename); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/oci_sample.c b/ProOracleSpatialCode/Code/Chapter-07/oci_sample.c new file mode 100644 index 0000000..ad231ea --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/oci_sample.c @@ -0,0 +1,389 @@ +/* oci_sample.c + + This program illustrates the basic operation of an OCI program. + It executes the following simple SQL statement to read information from + the US_CITIES table: + + SELECT ID, CITY, STATE_ABRV, POP90, RANK90 FROM US_CITIES; + + It illustrates the following concepts: + - setting up and tearing down the OCI environment + - connecting to and disconnecting from an Oracle database + - executing a SELECT statement + - using host ("defined") variables to read the results of a SELECT statement. + + The program takes the following command line arguments: + + oci_sample username password database + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Constants +*******************************************************************************/ +#define CITY_LENGTH 42 +#define STATE_ABRV_LENGTH 2 + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate(&envhp, OCI_DEFAULT+OCI_OBJECT, 0,0,0,0,0,0); + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc(envhp, &errhp, OCI_HTYPE_ERROR, 0, 0); + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadCities +** +** Description: Read all cities +*******************************************************************************/ +void ReadCities (void) +{ + int rows_fetched = 0; /* Row counter */ + char *select_sql; /* SQL Statement */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + + /* Define handles for host variables */ + OCIDefine *id_hp; + OCIDefine *city_hp; + OCIDefine *state_abrv_hp; + OCIDefine *pop90_hp; + OCIDefine *rank90_hp; + + /* Host variables */ + int id; + char city[CITY_LENGTH+1]; + char state_abrv[STATE_ABRV_LENGTH+1]; + double pop90; + long rank90; + + /* Construct the select statement */ + select_sql = "SELECT ID, CITY, STATE_ABRV, POP90, RANK90 FROM US_CITIES"; + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = ID (integer) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &id_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &id, /* (in) Value Pointer */ + sizeof(id), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = CITY (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &city_hp , /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + city, /* (in) Value Pointer */ + sizeof(city), /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 3 = STATE_ABRV (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &state_abrv_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)3, /* (in) Bind variable position */ + state_abrv, /* (in) Value Pointer */ + sizeof(state_abrv), /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 4 = POP90 (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &pop90_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)4, /* (in) Bind variable position */ + (dvoid *) &pop90, /* (in) Value Pointer */ + sizeof(pop90), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 5 = RANK90 (integer) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &rank90_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)5, /* (in) Bind variable position */ + (dvoid *) &rank90, /* (in) Value Pointer */ + sizeof(rank90), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first row of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + while (status != OCI_NO_DATA) + { + /* Display results just fetched */ + rows_fetched++; + printf ("Row %d: %d %s %s %f %d\n", rows_fetched, id, city, state_abrv, pop90, rank90); + + /* Fetch next row of result set */ + status = OCIStmtFetch( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch */ + (ub2)OCI_FETCH_NEXT, /* (in) Fetch direction */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + } + printf ("\n%d rows fetched\n", rows_fetched); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)select_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database; + + if( argc < 3 || argc > 4) { + printf("USAGE: %s [] \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + if (argc > 3) + database = argv[3]; + else + database = ""; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadCities(); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/oci_sample_array.c b/ProOracleSpatialCode/Code/Chapter-07/oci_sample_array.c new file mode 100644 index 0000000..59f8ad2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/oci_sample_array.c @@ -0,0 +1,426 @@ +/* oci_sample_array.c + + This program illustrates the basic operation of an OCI program. + It executes the following simple SQL statement to read information from + the US_CITIES table: + + SELECT ID, CITY, STATE_ABRV, POP90, RANK90 FROM US_CITIES; + + It is identical to oci_sample.c except that it fetches multiple rows + at a time (array fetches). + + It illustrates the following concepts: + - setting up and tearing down the OCI environment + - connecting to and disconnecting from an Oracle database + - executing a SELECT statement + - using host ("defined") variables to read the results of a SELECT statement. + - using array fetches + + The program takes the following command line arguments: + + oci_sample_array username password database [array_size] + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - array_size = number of rows to read per fetch (default is 10 rows) + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Constants +*******************************************************************************/ +#define CITY_LENGTH 42 +#define STATE_ABRV_LENGTH 2 + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadCities +** +** Description: Read all cities +*******************************************************************************/ +void ReadCities (int array_size) +{ + int rows_fetched = 0; /* Row counter */ + int nr_fetches = 0; /* Number of batches fetched */ + int rows_in_batch = 0; /* Number of rows in current batch */ + boolean has_more_data; + char *select_sql; /* SQL Statement */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + int i, j, k; + + /* Define handles for host variables */ + OCIDefine *id_hp; + OCIDefine *city_hp; + OCIDefine *state_abrv_hp; + OCIDefine *pop90_hp; + OCIDefine *rank90_hp; + + /* Host variables */ + int id[array_size]; + char city[array_size][CITY_LENGTH+1]; + char state_abrv[array_size][STATE_ABRV_LENGTH+1]; + double pop90[array_size]; + long rank90[array_size]; + + /* Construct the select statement */ + select_sql = "SELECT ID, CITY, STATE_ABRV, POP90, RANK90 FROM US_CITIES"; + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = ID (integer) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &id_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &id, /* (in) Value Pointer */ + sizeof(int), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = CITY (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &city_hp , /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + city, /* (in) Value Pointer */ + CITY_LENGTH+1, /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 3 = STATE_ABRV (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &state_abrv_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)3, /* (in) Bind variable position */ + state_abrv, /* (in) Value Pointer */ + STATE_ABRV_LENGTH+1, /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 4 = POP90 (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &pop90_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)4, /* (in) Bind variable position */ + (dvoid *) &pop90, /* (in) Value Pointer */ + sizeof(double), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 5 = RANK90 (integer) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &rank90_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)5, /* (in) Bind variable position */ + (dvoid *) &rank90, /* (in) Value Pointer */ + sizeof(long), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first batch of rows of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)array_size, /* (in) Number of rows to fetch */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + has_more_data = TRUE; + do + { + /* Check if this is the last (or only) batch. + The Execute and Fetch calls return OCI_NO_DATA to indicate that the batch + they returned is the last one, i.e. that no further calls to OCIStmtFetch are needed. + The returned batch still needs to be processed */ + if (status == OCI_NO_DATA) + has_more_data = FALSE; + + /* Get the number of rows returned in current batch */ + OCIAttrGet( + (dvoid *)select_stmthp, + (ub4)OCI_HTYPE_STMT, + (dvoid *)&rows_in_batch, + (ub4 *)0, + (ub4)OCI_ATTR_ROWS_FETCHED, + errhp); + + nr_fetches++; + + /* Display results just fetched */ + for (i=0; i 5) { + printf("USAGE: %s [] []\n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + if (argc > 3) + database = argv[3]; + else + database = ""; + if (argc > 4) + array_size = atoi(argv[4]); + else + array_size = 10; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadCities(array_size); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/preadgeom.pc b/ProOracleSpatialCode/Code/Chapter-07/preadgeom.pc new file mode 100644 index 0000000..9b85204 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/preadgeom.pc @@ -0,0 +1,186 @@ +#include +#include + +EXEC SQL INCLUDE SQLCA ; +EXEC SQL INCLUDE oraca.h ; +EXEC SQL BEGIN DECLARE SECTION ; +#include "geometry.h" +EXEC SQL END DECLARE SECTION ; + +#define DEBUG 1 +#define MAX_ORDINATES 32768 + +EXEC SQL WHENEVER SQLERROR DO SqlError(); + +void SqlError() +{ + char err_msg[128]; + int buf_len, msg_len; + + buf_len = sizeof (err_msg); + sqlglm(err_msg, &buf_len, &msg_len); + printf("SQL Error: %.*s\n", msg_len, err_msg); + exit(1); +} + + +DumpGeometry( + SDO_GEOMETRY *geometry, + SDO_GEOMETRY_ind *geometryInd, + long ordinateArraySize + ) +{ + EXEC SQL BEGIN DECLARE SECTION; + SDO_GEOMETRY *geometryObject ; + SDO_POINT_TYPE *pointObject; + SDO_ELEM_INFO_ARRAY *elemInfoArrayObject ; + SDO_ORDINATE_ARRAY *ordinateArrayObject ; + SDO_GEOMETRY_ind *geometryObjectInd ; + SDO_POINT_TYPE_ind *pointObjectInd; + long nOrdinates; + long nElemInfo; + int gType; + int srId; + double x, y, z; + double ordinateValue; + double *ordinateArray; + int elementInfoValue; + long nOrdinatesSection; + EXEC SQL END DECLARE SECTION; + + long i, j, k, n; + + geometryObject = geometry; + geometryObjectInd = geometryInd; + + printf ("SDO_GEOMETRY("); + + if (geometryInd->SDO_GTYPE == 0) { + EXEC SQL OBJECT GET SDO_GTYPE FROM :geometryObject INTO :gType ; + printf ("%d, ", gType); + } + else + printf ("NULL, "); + + if (geometryInd->SDO_SRID == 0) { + EXEC SQL OBJECT GET SDO_SRID FROM :geometryObject INTO :srId ; + printf ("%d, ", srId); + } + else + printf ("NULL, "); + + pointObject = &(geometryObject->SDO_POINT); + pointObjectInd = &(geometryObjectInd->SDO_POINT); + if (pointObjectInd->_atomic == 0) { + printf ("SDO_POINT("); + if (pointObjectInd->X == 0) { + EXEC SQL OBJECT GET X FROM :pointObject INTO :x; + printf ("%g, ", x); + } + else + printf ("NULL, "); + if (pointObjectInd->Y == 0) { + EXEC SQL OBJECT GET Y FROM :pointObject INTO :y; + printf ("%g, ", y); + } + else + printf ("NULL, "); + if (pointObjectInd->Z == 0) { + EXEC SQL OBJECT GET Z FROM :pointObject INTO :z; + printf ("%g", z); + } + else + printf ("NULL"); + printf ("), "); + } + else + printf ("NULL, "); + + if (geometryInd->SDO_ELEM_INFO == 0) { + EXEC SQL ALLOCATE :elemInfoArrayObject; + EXEC SQL OBJECT GET SDO_ELEM_INFO FROM :geometryObject INTO :elemInfoArrayObject ; + EXEC SQL COLLECTION DESCRIBE :elemInfoArrayObject GET SIZE INTO :nElemInfo; + printf ("SDO_ELEM_INFO_ARRAY("); + for (i=1; i<=nElemInfo; i++) { + EXEC SQL COLLECTION GET :elemInfoArrayObject INTO :elementInfoValue; + printf ("%d",elementInfoValue); + if (i < nElemInfo) + printf (", "); + } + printf ("), "); + } + else + printf ("NULL, "); + + if (geometryInd->SDO_ORDINATES == 0) { + EXEC SQL ALLOCATE :ordinateArrayObject; + EXEC SQL OBJECT GET SDO_ORDINATES FROM :geometryObject INTO :ordinateArrayObject ; + EXEC SQL COLLECTION DESCRIBE :ordinateArrayObject GET SIZE INTO :nOrdinates; + ordinateArray = (double *) calloc (ordinateArraySize, (size_t)sizeof(double)); + printf ("SDO_ORDINATE_ARRAY("); + if (DEBUG) + printf ("\n[Getting %d ordinates]\n", nOrdinates); + for (i=0; i ordinateArraySize) + nOrdinatesSection = ordinateArraySize; + if (DEBUG) + printf (" [Getting %d ordinates [%d:%d]]\n",nOrdinatesSection, i+1, i+nOrdinatesSection); + EXEC SQL FOR :nOrdinatesSection + COLLECTION GET :ordinateArrayObject INTO :ordinateArray; + if (DEBUG) + if (sqlca.sqlerrd[2] != nOrdinatesSection) + printf (" [***** error: only %d ordinates returned - %d missing]\n", + sqlca.sqlerrd[2], nOrdinatesSection - sqlca.sqlerrd[2]); + //printf ("%g", ordinateValue); + //if (i < nOrdinates) + // printf (", "); + } + printf (")"); + } + else + printf ("NULL"); + + printf (")\n"); +} + +int main(int argc, char **argv) { + + EXEC SQL BEGIN DECLARE SECTION; + char *connectionString; + long id; + char *sqlQuery; + SDO_GEOMETRY *geometryObject; + SDO_GEOMETRY_ind *geometryObjectInd; + EXEC SQL END DECLARE SECTION; + long ordinateArraySize; + int i; + + if (argc <= 2) { + printf ("Usage: %s \n", argv[0]); + exit(1); + } + + i = 1; + connectionString = argv[i++]; + id = atoi(argv[i++]); + if (argc > 3) + ordinateArraySize = atoi(argv[i++]); + else + ordinateArraySize = MAX_ORDINATES; + + printf ("Connecting to database: %s\n", connectionString); + EXEC SQL CONNECT :connectionString ; + + EXEC SQL ALLOCATE :geometryObject :geometryObjectInd ; + + printf ("Fetching geometry %d - %d ordinates at a time\n", id, ordinateArraySize); + EXEC SQL SELECT GEOM INTO :geometryObject + FROM TEST WHERE ID = :id; + + DumpGeometry ( geometryObject, geometryObjectInd, ordinateArraySize ); + + EXEC SQL COMMIT; + + printf ("Done\n"); +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/pwritegeom.pc b/ProOracleSpatialCode/Code/Chapter-07/pwritegeom.pc new file mode 100644 index 0000000..88ba0fe --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/pwritegeom.pc @@ -0,0 +1,308 @@ +#include +#include +#include +#include "geometry.h" + +EXEC SQL INCLUDE SQLCA ; +EXEC SQL INCLUDE oraca.h ; +EXEC SQL BEGIN DECLARE SECTION ; +#include "geometry.h" +EXEC SQL END DECLARE SECTION ; + +#define DEBUG 1 +#define MAX_ORDINATES 32768 + +struct Point +{ + double x; + double y; +}; +typedef struct Point Point; + + +EXEC SQL WHENEVER SQLERROR DO SqlError(); + +void SqlError() +{ + char err_msg[128]; + int buf_len, msg_len; + + buf_len = sizeof (err_msg); + sqlglm(err_msg, &buf_len, &msg_len); + printf("SQL Error: %.*s\n", msg_len, err_msg); + exit(1); +} + +void *MakeGeometry ( + SDO_GEOMETRY **PgeometryObject, + SDO_GEOMETRY_ind **PgeometryObjectInd, + int PgType, + int PsrId, + long PnElemInfo, + long *PelemInfoArray, + long PnOrdinates, + double *PordinateArray + ) +{ + EXEC SQL BEGIN DECLARE SECTION; + int gType; + int srId; + long nElemInfo; + long *elemInfoArray; + long nOrdinates; + double *ordinateArray; + double *ordinateArraySection; + long nOrdinatesSection; + double x, y, z; + SDO_GEOMETRY *geometryObject ; + SDO_GEOMETRY_ind *geometryObjectInd; + SDO_ORDINATE_ARRAY *ordinateArrayObject ; + SDO_ELEM_INFO_ARRAY *elemInfoArrayObject ; + SDO_POINT_TYPE *pointObject; + SDO_POINT_TYPE_ind *pointObjectInd; + EXEC SQL END DECLARE SECTION; + + long i; + + /* Copy parameters into the SQL declaration section */ + gType = PgType; + srId = PsrId; + nElemInfo = PnElemInfo; + elemInfoArray = PelemInfoArray; + nOrdinates = PnOrdinates; + ordinateArray = PordinateArray; + geometryObject = *PgeometryObject; + geometryObjectInd = *PgeometryObjectInd; + + if (DEBUG) + printf ("Constructing geometry: GTYPE:%d SRID:%d ELEM_INFO: [%d] ORDINATES: [%d]\n", + gType, srId, nElemInfo, nOrdinates); + + /* Allocate an SDO_GEOMETRY object */ + if (geometryObject == 0) { + printf ("Allocate a geometry object in the object cache\n"); + EXEC SQL ALLOCATE :geometryObject :geometryObjectInd; + } + + /* Construct the SDO_ELEM_INFO_ARRAY object */ + + /* Allocate an object of type SDO_ELEM_INFO_ARRAY */ + EXEC SQL ALLOCATE :elemInfoArrayObject ; + /* Populate the SDO_ELEM_INFO_ARRAY object with the input array */ + EXEC SQL FOR :nElemInfo COLLECTION APPEND :elemInfoArray TO :elemInfoArrayObject; + if (DEBUG) + if (sqlca.sqlerrd[2] != nElemInfo) + printf (" [***** error: only %d elem info stored - %d missing]\n", + sqlca.sqlerrd[2], nElemInfo - sqlca.sqlerrd[2]); + + /* Construct the SDO_ORDINATE_ARRAY object */ + + /* NOTE: + The COLLECTION SET statement is only able to append up to 32768 elements + at a time. So, we have to break the input into chunks of 32768 elements and + repeat the COLLECTION SET operation as many times as needed + */ + + /* Allocate an object of type SDO_ORDINATE_ARRAY */ + EXEC SQL ALLOCATE :ordinateArrayObject; + /* Populate the SDO_ORDINATE_ARRAY object with the input array */ + for (i=0; i MAX_ORDINATES) + nOrdinatesSection = MAX_ORDINATES; + ordinateArraySection = &ordinateArray[i]; + if (DEBUG) + printf ("adding %d ordinates [%d:%d]\n",nOrdinatesSection, i, i+nOrdinatesSection-1); + EXEC SQL FOR :nOrdinatesSection COLLECTION APPEND :ordinateArraySection TO:ordinateArrayObject; + if (DEBUG) + if (sqlca.sqlerrd[2] != nOrdinatesSection) + printf (" [***** error: only %d ordinates stored - %d missing]\n", + sqlca.sqlerrd[2], nOrdinatesSection - sqlca.sqlerrd[2]); + } + + /* Construct the SDO_GEOMETRY object */ + /* Set object attributes */ + EXEC SQL OBJECT SET SDO_GTYPE, SDO_SRID, SDO_ELEM_INFO, SDO_ORDINATES + OF :geometryObject + TO :gType, :srId, :elemInfoArrayObject, :ordinateArrayObject; + + /* Set indicators */ + pointObjectInd = &(geometryObjectInd->SDO_POINT); + geometryObjectInd->_atomic = 0; + geometryObjectInd->SDO_GTYPE = 0; + geometryObjectInd->SDO_SRID = 0 ; + geometryObjectInd->SDO_ELEM_INFO = 0; + geometryObjectInd->SDO_ORDINATES = 0; + pointObjectInd->_atomic = -1; + + /* Free the SDO_ELEM_INFO_ARRAY and SDO_ORDINATE_ARRAY objects */ + EXEC SQL FREE :elemInfoArrayObject ; + EXEC SQL FREE :ordinateArrayObject; + + /* Return object and its indicators to the caller */ + *PgeometryObject = geometryObject; + *PgeometryObjectInd = geometryObjectInd; + +} + +void MakePoint ( + SDO_GEOMETRY **PgeometryObject, + SDO_GEOMETRY_ind **PgeometryObjectInd, + int PgType, + int PsrId, + double Px, + double Py, + double Pz + ) +{ + EXEC SQL BEGIN DECLARE SECTION; + int gType; + int srId; + double x, y, z; + SDO_GEOMETRY *geometryObject ; + SDO_GEOMETRY_ind *geometryObjectInd; + SDO_POINT_TYPE *pointObject; + SDO_POINT_TYPE_ind *pointObjectInd; + EXEC SQL END DECLARE SECTION; + + long i; + + /* Copy parameters into the SQL declaration section so they can be used in SQL statements */ + gType = PgType; + srId = PsrId; + x = Px; + y = Py; + z = Pz; + geometryObject = *PgeometryObject; + geometryObjectInd = *PgeometryObjectInd; + + if (DEBUG) + printf ("Constructing point: GTYPE:%d SRID:%d POINT: %g,%g,%g\n", gType, srId, x, y, z); + + /* Allocate an SDO_GEOMETRY object */ + if (geometryObject == 0) { + printf ("Allocate a geometry object in the object cache\n"); + EXEC SQL ALLOCATE :geometryObject :geometryObjectInd; + } + + /* set X, Y and Z attributes in SDO_POINT object */ + pointObject = &(geometryObject->SDO_POINT); + EXEC SQL OBJECT SET X, Y, Z OF :pointObject TO :x, :y, :z; + + /* Set indicators + SDO_ELEM_INFO and SDO_ORDINATES to NULL */ + pointObjectInd = &(geometryObjectInd->SDO_POINT); + geometryObjectInd->_atomic = 0; + geometryObjectInd->SDO_GTYPE = 0; + geometryObjectInd->SDO_SRID = 0 ; + geometryObjectInd->SDO_ELEM_INFO = -1; + geometryObjectInd->SDO_ORDINATES = -1; + pointObjectInd->_atomic = 0; + pointObjectInd->X = 0; + pointObjectInd->Y = 0; + pointObjectInd->Z = 0; + + /* set SDO_GTYPE and SDO_SRID attributes in SDO_GEOMETRY object */ + EXEC SQL OBJECT SET SDO_GTYPE, SDO_SRID OF :geometryObject :geometryObjectInd TO :gType, :srId; + + /* Return object and its indicators to the caller */ + *PgeometryObject = geometryObject; + *PgeometryObjectInd = geometryObjectInd; +} + +void *Make2DPolygon( + SDO_GEOMETRY **PgeometryObject, + SDO_GEOMETRY_ind **PgeometryObjectInd, + long nPoints, + Point *pointArray + ) +{ + long elemInfoArray[3]; + long nOrdinates; + double *ordinateArray; + long i, j, k, n; + + /* Fill elem_info array */ + elemInfoArray[0] = 1 ; + elemInfoArray[1] = 1003 ; + elemInfoArray[2] = 1 ; + + /* Allocate space for ordinate array */ + ordinateArray = (double *) calloc (nPoints*2, (size_t)sizeof(double)); + /* Fill ordinate array */ + i = 0; + for (j=0; j [] []\n", argv[0]); + exit(1); + } + /* Get arguments */ + i = 1; + connectionString = argv[i++]; + id = atoi (argv[i++]); + if (argc > 3) + nGeoms = atoi (argv[i++]); + else + nGeoms = 1; + if (argc > 4) + nPoints = atoi (argv[i++]); + else + nPoints = 0; + /* initialize randomizer */ + srand(time(0)); + /* Connect to database */ + printf ("Connecting to database: %s\n", connectionString); + EXEC SQL CONNECT :connectionString ; + for (i=0; i 0) { + printf ("Generating %d points polygon\n", nPoints); + points = (Point *) calloc (nPoints, (size_t)sizeof(Point)); + for (j=0; j +#include +#include +#include +#include "sdo_geometry.h" + +#define use_array_interface 0 + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Types and structures +*******************************************************************************/ + +struct point { + double x; + double y; + double z; +}; +typedef struct point point_struct; + +struct geometry +{ + int gtype; + int srid; + struct point *point; + int n_elem_info; + int *elem_info; + int n_ordinates; + double *ordinates; +}; +typedef struct geometry geometry_struct; + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = -1; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "ERROR %d: %s\n", errcode, errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT+OCI_OBJECT), /* (in) Mode: handles objects */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: LoadGeometry +** +** Description: Load a geometry from an SDO_GEOMETRY object structure +** into a C memory structure. +*******************************************************************************/ +geometry_struct *LoadGeometry ( + SDO_GEOMETRY *geometry_object, + SDO_GEOMETRY_ind *geometry_object_ind +) +{ + geometry_struct *geometry; + double x, y, z; + boolean exists; + OCINumber *oci_number; + long i; + static OCINumber *global_oci_number = NULL; + static boolean *global_exists = NULL; + int status; + + if (geometry_object_ind->_atomic == OCI_IND_NULL) { + geometry = NULL; + return geometry; + } + + /* Allocate geometry structure */ + geometry = malloc (sizeof(geometry_struct)); + + /* Extract SDO_GTYPE */ + if (geometry_object_ind->SDO_GTYPE == OCI_IND_NOTNULL) { + OCINumberToInt ( + errhp, + &(geometry_object->SDO_GTYPE), + (uword) sizeof (int), + OCI_NUMBER_SIGNED, + (dvoid *) & geometry->gtype); + } + else + geometry->gtype = 0; + + /* Extract SDO_SRID */ + if (geometry_object_ind->SDO_SRID == OCI_IND_NOTNULL) { + OCINumberToInt ( + errhp, + &(geometry_object->SDO_SRID), + (uword) sizeof (int), + OCI_NUMBER_SIGNED, + (dvoid *) & geometry->srid); + } + else + geometry->srid = 0; + + /* Extract SDO_POINT */ + geometry->point = 0; + if (geometry_object_ind->SDO_POINT._atomic == OCI_IND_NOTNULL) { + x = y = z = 0; + /* Allocate space for point structure */ + geometry->point = malloc (sizeof(point_struct)); + /* Extract X */ + if (geometry_object_ind->SDO_POINT.X == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.X), (uword)sizeof(double), (dvoid *)&x); + /* Extract Y */ + if (geometry_object_ind->SDO_POINT.Y == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.Y), (uword)sizeof(double), (dvoid *)&y); + /* Extract Z */ + if (geometry_object_ind->SDO_POINT.Z == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.Z), (uword)sizeof(double), (dvoid *)&z); + /* Fill point structure */ + geometry->point->x = x; + geometry->point->y = y; + geometry->point->z = z; + } + + /* Extract SDO_ELEM_INFO array */ + + /* Get the size of the array */ + OCICollSize (envhp, errhp, + (OCIColl *)(geometry_object->SDO_ELEM_INFO), &geometry->n_elem_info); + + if (geometry->n_elem_info > 0) { + + /* Allocate memory for the array */ + geometry->elem_info = malloc (sizeof(int)*geometry->n_elem_info); + + /* Get all elements in the array */ + /* Loop over array elements and process one by one */ + for (i=0; in_elem_info; i++) { + /* Extract one element from the varray */ + OCICollGetElem(envhp, errhp, + (OCIColl *) (geometry_object->SDO_ELEM_INFO), + (sb4) (i), + (boolean *) &exists, + (dvoid **) &oci_number, + (dvoid **) 0 + ); + /* Convert the element to int */ + OCINumberToInt(errhp, oci_number, + (uword)sizeof(int), + OCI_NUMBER_UNSIGNED, + (dvoid *)&geometry->elem_info[i] + ); + } + + } else + geometry->elem_info = NULL; + + /* Extract SDO_ORDINATES array */ + + /* Get the size of the array */ + OCICollSize(envhp, errhp, + (OCIColl *)(geometry_object->SDO_ORDINATES), &geometry->n_ordinates); + + if (geometry->n_ordinates > 0) { + + /* Allocate memory */ + geometry->ordinates = malloc (sizeof(double)*geometry->n_ordinates); + + /* Get all elements in the array */ + if (use_array_interface) { + + /* Use the collection array interface: process all elements at once */ + + /* (Re)allocate space for intermediate vectors */ + global_oci_number = (OCINumber *)malloc(sizeof(OCINumber *) * geometry->n_ordinates); + global_exists = (boolean *)malloc(sizeof(boolean) * geometry->n_ordinates); + + /* Extract all elements from the varray */ + status = OCICollGetElemArray (envhp, errhp, + (OCIColl *) geometry_object->SDO_ORDINATES, /* Collection to process */ + (sb4) (0), /* Index of first element to fetch */ + (boolean *) global_exists, /* Pointer to output array of presence flags */ + (dvoid **) &global_oci_number, /* Pointer to output array of OCINumber */ + (dvoid **) 0, /* Pointer to output array of indicators (not used) */ + &(geometry->n_ordinates) /* Number of elements to extract */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + for (i=0; in_ordinates; i++) { + printf ("global_oci_number[%d]=%0X\n", i, global_oci_number[0]); + } + /* Convert all extracted elements to double */ + OCINumberToRealArray (errhp, + (const OCINumber **) &global_oci_number, /* Pointer to input array of OCINumber */ + geometry->n_ordinates, /* Number of elements to convert */ + (uword) sizeof (double), /* Size of output element */ + (dvoid *) geometry->ordinates); /* Pointer to output array of double */ + } + else + { + /* Loop over array elements and process one by one */ + for (i=0; in_ordinates; i++) { + + /* extract one element from the varray */ + OCICollGetElem(envhp, errhp, + (OCIColl *) (geometry_object->SDO_ORDINATES), + (sb4) (i), + (boolean *) &exists, + (dvoid **) &oci_number, + (dvoid **) 0 + ); + /* convert the element to double */ + OCINumberToReal(errhp, oci_number, + (uword)sizeof(double), + (dvoid *)&(geometry->ordinates[i]) + ); + } + } + + } else + geometry->ordinates = NULL; + + return (geometry); +} + +/******************************************************************************* +** Routine: FreeGeometry +** +** Description: Frees the memory used for a geometry structure +*******************************************************************************/ +void FreeGeometry (geometry_struct *geometry) { + if (geometry != 0) { + /* Free memory used for the point structure */ + if (geometry->point != NULL) + free (geometry->point); + /* Free memory used for the elem_info vector */ + if (geometry->elem_info != 0) + free (geometry->elem_info); + /* Free memory used for the ordinates vector */ + if (geometry->ordinates != 0) + free (geometry->ordinates); + /* Free memory used for the geometry structure */ + free (geometry); + } +} + +/******************************************************************************* +** Routine: PrintGeometry +** +** Description: Print out a geometry +*******************************************************************************/ +void PrintGeometry ( + geometry_struct *geometry, + int row_number, + int print_level +) +{ + long i; + int gtype; + char *gtype_name; + int dim; + int n_elements; + int n_points; + + gtype = geometry->gtype % 1000; + dim = geometry->gtype / 1000; + n_elements = geometry->n_elem_info / 3; + n_points = geometry->n_ordinates / dim; + switch (gtype) { + case 1: + gtype_name = "POINT"; + break; + case 2: + gtype_name = "LINESTRING"; + break; + case 3: + gtype_name = "POLYGON"; + break; + case 4: + gtype_name = "COLLECTION"; + break; + case 5: + gtype_name = "MULTI-POINT"; + break; + case 6: + gtype_name = "MULTI-LINESTRING"; + break; + case 7: + gtype_name = "MULTI-POLYGON"; + break; + } + + if (print_level >= 1) { + printf ("Row %d: ", row_number); + printf ("Geometry\n"); + printf (" Type: %d (%s)\n", gtype, gtype_name); + printf (" Dimensions: %d\n", dim); + printf (" Spatial reference system: %d\n", geometry->srid); + printf (" Elements: %d\n", n_elements); + printf (" Points: %d\n", n_points); + } + + if (print_level >= 2) { + printf ("Detailed structure\n"); + printf (" SDO_GTYPE: %d\n", geometry->gtype); + printf (" SDO_SRID: %d\n", geometry->srid); + if (geometry->point != NULL) + printf (" SDO_POINT: (%f, %f, %f)\n", + geometry->point->x, geometry->point->y, geometry->point->z); + if (geometry->n_elem_info > 0) + printf (" SDO_ELEM_INFO (%d elements)\n", geometry->n_elem_info); + for (i=0; in_elem_info; i++) + printf (" [%d]=%d\n", i+1, geometry->elem_info[i]); + if (geometry->n_ordinates > 0) + printf (" SDO_ORDINATES (%d elements)\n", geometry->n_ordinates); + for (i=0; in_ordinates; i++) + printf (" [%d]=%f\n", i+1, geometry->ordinates[i]); + } +} + +/******************************************************************************* +** Routine: ReadGeometries +** +** Description: Read all geometries returned by the select statement provided +*******************************************************************************/ +void ReadGeometries ( + char *select_statement, + int print_level) +{ + int rows_fetched = 0; /* Row counter */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + + /* Define handles for host variables */ + OCIDefine *geometry_hp; + + /* Type descriptor for geometry object type */ + OCIType *geometry_type_desc; + + /* Host variables */ + SDO_GEOMETRY *geometry_obj = NULL; + SDO_GEOMETRY_ind *geometry_ind = NULL; + + geometry_struct *geometry; + + /* Construct the select statement */ + printf ("Executing query:\nSQL> %s\n\n", select_statement); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_statement, /* (in) SQL statement */ + (ub4)strlen(select_statement), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get type descriptor for geometry object type */ + status = OCITypeByName ( + (dvoid *)envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + svchp, /* (in) Service Context Handle */ + "MDSYS", /* (in) Type owner name */ + strlen("MDSYS"), /* (in) (length) */ + "SDO_GEOMETRY", /* (in) Type name */ + strlen("SDO_GEOMETRY"), /* (in) (length) */ + 0, /* (in) Version name (NOT USED) */ + 0, /* (in) (length) */ + OCI_DURATION_SESSION, /* (in) Pin duration */ + OCI_TYPEGET_HEADER , /* (in) Get option */ + &geometry_type_desc); /* (out) Type descriptor */ + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = geometry (ADT) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &geometry_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *)0, /* (in) Value Pointer (NOT USED) */ + 0, /* (in) Value Size (NOT USED) */ + SQLT_NTY, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED) */ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + status = OCIDefineObject( + geometry_hp, /* (in) Define handle */ + errhp, /* (in) Error handle */ + geometry_type_desc, /* (in) Geometry type descriptor */ + (dvoid **) &geometry_obj, /* (in) Value Pointer */ + (ub4 *)0, /* (in) Value Size (NOT USED) */ + (dvoid **) &geometry_ind, /* (in) Indicator Pointer */ + (ub4 *)0 /* (in) Indicator Size */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first row of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + while (status != OCI_NO_DATA) + { + rows_fetched++; + + /* Import geometry from SDO_GEOMETRY OCI structure into C structure */ + geometry = LoadGeometry (geometry_obj, geometry_ind); + + /* Print the geometry just imported */ + PrintGeometry (geometry, rows_fetched, print_level); + + /* Release memory used for the geometry structure */ + FreeGeometry (geometry); + + /* Fetch next row of result set */ + status = OCIStmtFetch( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch */ + (ub2)OCI_FETCH_NEXT, /* (in) Fetch direction */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + } + printf ("\n%d rows fetched\n", rows_fetched); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)select_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database, *select_statement; + int print_level; + + if( argc != 6) { + printf("USAGE: %s \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + select_statement = argv[4]; + print_level = atoi (argv[5]); + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadGeometries(select_statement, print_level); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} +/* read_points.c + + This program selects point objects from a table in the database. + + It reads the points without using object types, i.e by extracting + the X and Y values of each point, using the following syntax: + + SELECT C.geo_column.SDO_POINT.X, C.geo_column.SDO_POINT.Y + FROM tablename C + + It illustrates the following concepts: + - dynamically constructing SQL statements + - reading point details without using objects + + The program takes the following command line arguments: + + read_points username password database tablename geo_column + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - tablename = name of points table to select from + - geo_column = name of the geometry column to read + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadPoints +** +** Description: Read all points +*******************************************************************************/ +void ReadPoints ( + char *tablename, + char *geocolumn) +{ + int rows_fetched = 0; /* Row counter */ + char select_sql[1024]; /* SQL Statement */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + + /* Define handles for host variables */ + OCIDefine *point_x_hp; + OCIDefine *point_y_hp; + + /* Host variables */ + double point_x; + double point_y; + + /* Construct the select statement */ + sprintf (select_sql, "SELECT C.%s.SDO_POINT.X, C.%s.SDO_POINT.Y FROM %s C", geocolumn, geocolumn, tablename); + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = POINT_X (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_x_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &point_x, /* (in) Value Pointer */ + sizeof(point_x), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = POINT_Y (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_y_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + (dvoid *) &point_y, /* (in) Value Pointer */ + sizeof(point_y), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first row of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + while (status != OCI_NO_DATA) + { + /* Display results just fetched */ + rows_fetched++; + printf ("%d: (%f, %f)\n", rows_fetched, point_x, point_y); + + /* Fetch next row of result set */ + status = OCIStmtFetch( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch */ + (ub2)OCI_FETCH_NEXT, /* (in) Fetch direction */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + } + printf ("\n%d rows fetched\n", rows_fetched); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)select_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database, *tablename, *geocolumn; + + if( argc != 6) { + printf("USAGE: %s \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + tablename = argv[4]; + geocolumn = argv[5]; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadPoints(tablename, geocolumn); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/read_geom_array.c b/ProOracleSpatialCode/Code/Chapter-07/read_geom_array.c new file mode 100644 index 0000000..e91b6a4 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/read_geom_array.c @@ -0,0 +1,705 @@ +/* read_geom_array.c + + This program reads geometry objects from a table in the database. + + The geometry objects can be of any kind. Each object is first + loaded into a C structure, from which it is then printed out. + + The input to the program is a SELECT statement that returns a single + column of type SDO_GEOMETRY. + + It is identical to read_geom.c except that it fetches multiple rows + at a time (array fetches). + + It illustrates the following concepts: + - passing SQL statements from the command line + - reading and decoding geometry objects + - using array fetches + + The program takes the following command line arguments: + + read_geom username password database select_statement print_level [array_size] + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - print_level = level of detail to print out + 0 = do not print geometries + 1 = print summary (type, number of elements, number of points) + 2 = print details (all elements and point details) + - array_size = number of rows to read per fetch (default is 10 rows) + +*/ +#include +#include +#include +#include +#include +#include "sdo_geometry.h" + +#define use_array_interface 0 +#define TRACE() {printf ("TRACE: %d\n", __LINE__);} + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Types and structures +*******************************************************************************/ + +struct point { + double x; + double y; + double z; +}; +typedef struct point point_struct; + +struct geometry +{ + int gtype; + int srid; + struct point *point; + int n_elem_info; + int *elem_info; + int n_ordinates; + double *ordinates; +}; +typedef struct geometry geometry_struct; + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = -1; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "ERROR %d: %s\n", errcode, errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT+OCI_OBJECT), /* (in) Mode: handles objects */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: LoadGeometry +** +** Description: Load a geometry from an SDO_GEOMETRY object structure +** into a C memory structure. +*******************************************************************************/ +geometry_struct *LoadGeometry ( + SDO_GEOMETRY *geometry_object, + SDO_GEOMETRY_ind *geometry_object_ind +) +{ + geometry_struct *geometry; + double x, y, z; + boolean exists; + OCINumber *oci_number; + long i; + static OCINumber *global_oci_number = NULL; + static boolean *global_exists = NULL; + int status; + + if (geometry_object_ind->_atomic == OCI_IND_NULL) { + geometry = NULL; + return geometry; + } + + /* Allocate geometry structure */ + geometry = malloc (sizeof(geometry_struct)); + + /* Extract SDO_GTYPE */ + if (geometry_object_ind->SDO_GTYPE == OCI_IND_NOTNULL) { + OCINumberToInt ( + errhp, + &(geometry_object->SDO_GTYPE), + (uword) sizeof (int), + OCI_NUMBER_SIGNED, + (dvoid *) & geometry->gtype); + } + else + geometry->gtype = 0; + + /* Extract SDO_SRID */ + if (geometry_object_ind->SDO_SRID == OCI_IND_NOTNULL) { + OCINumberToInt ( + errhp, + &(geometry_object->SDO_SRID), + (uword) sizeof (int), + OCI_NUMBER_SIGNED, + (dvoid *) & geometry->srid); + } + else + geometry->srid = 0; + + /* Extract SDO_POINT */ + geometry->point = 0; + if (geometry_object_ind->SDO_POINT._atomic == OCI_IND_NOTNULL) { + x = y = z = 0; + /* Allocate space for point structure */ + geometry->point = malloc (sizeof(point_struct)); + /* Extract X */ + if (geometry_object_ind->SDO_POINT.X == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.X), (uword)sizeof(double), (dvoid *)&x); + /* Extract Y */ + if (geometry_object_ind->SDO_POINT.Y == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.Y), (uword)sizeof(double), (dvoid *)&y); + /* Extract Z */ + if (geometry_object_ind->SDO_POINT.Z == OCI_IND_NOTNULL) + OCINumberToReal( + errhp, &(geometry_object->SDO_POINT.Z), (uword)sizeof(double), (dvoid *)&z); + /* Fill point structure */ + geometry->point->x = x; + geometry->point->y = y; + geometry->point->z = z; + } + + /* Extract SDO_ELEM_INFO array */ + + /* Get the size of the array */ + OCICollSize (envhp, errhp, + (OCIColl *)(geometry_object->SDO_ELEM_INFO), &geometry->n_elem_info); + + if (geometry->n_elem_info > 0) { + + /* Allocate memory for the array */ + geometry->elem_info = malloc (sizeof(int)*geometry->n_elem_info); + + /* Get all elements in the array */ + /* Loop over array elements and process one by one */ + for (i=0; in_elem_info; i++) { + /* Extract one element from the varray */ + OCICollGetElem(envhp, errhp, + (OCIColl *) (geometry_object->SDO_ELEM_INFO), + (sb4) (i), + (boolean *) &exists, + (dvoid **) &oci_number, + (dvoid **) 0 + ); + /* Convert the element to int */ + OCINumberToInt(errhp, oci_number, + (uword)sizeof(int), + OCI_NUMBER_UNSIGNED, + (dvoid *)&geometry->elem_info[i] + ); + } + + } else + geometry->elem_info = NULL; + + /* Extract SDO_ORDINATES array */ + + /* Get the size of the array */ + OCICollSize(envhp, errhp, + (OCIColl *)(geometry_object->SDO_ORDINATES), &geometry->n_ordinates); + + if (geometry->n_ordinates > 0) { + + /* Allocate memory */ + geometry->ordinates = malloc (sizeof(double)*geometry->n_ordinates); + + /* Get all elements in the array */ + if (use_array_interface) { + + /* Use the collection array interface: process all elements at once */ + + /* (Re)allocate space for intermediate vectors */ + global_oci_number = (OCINumber *)malloc(sizeof(OCINumber *) * geometry->n_ordinates); + global_exists = (boolean *)malloc(sizeof(boolean) * geometry->n_ordinates); + + /* Extract all elements from the varray */ + status = OCICollGetElemArray (envhp, errhp, + (OCIColl *) geometry_object->SDO_ORDINATES, /* Collection to process */ + (sb4) (0), /* Index of first element to fetch */ + (boolean *) global_exists, /* Pointer to output array of presence flags */ + (dvoid **) &global_oci_number, /* Pointer to output array of OCINumber */ + (dvoid **) 0, /* Pointer to output array of indicators (not used) */ + &(geometry->n_ordinates) /* Number of elements to extract */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + for (i=0; in_ordinates; i++) { + printf ("global_oci_number[%d]=%0X\n", i, global_oci_number[0]); + } + /* Convert all extracted elements to double */ + OCINumberToRealArray (errhp, + (const OCINumber **) &global_oci_number, /* Pointer to input array of OCINumber */ + geometry->n_ordinates, /* Number of elements to convert */ + (uword) sizeof (double), /* Size of output element */ + (dvoid *) geometry->ordinates); /* Pointer to output array of double */ + } + else + { + /* Loop over array elements and process one by one */ + for (i=0; in_ordinates; i++) { + + /* extract one element from the varray */ + OCICollGetElem(envhp, errhp, + (OCIColl *) (geometry_object->SDO_ORDINATES), + (sb4) (i), + (boolean *) &exists, + (dvoid **) &oci_number, + (dvoid **) 0 + ); + /* convert the element to double */ + OCINumberToReal(errhp, oci_number, + (uword)sizeof(double), + (dvoid *)&(geometry->ordinates[i]) + ); + } + } + + } else + geometry->ordinates = NULL; + + return (geometry); +} + +/******************************************************************************* +** Routine: FreeGeometry +** +** Description: Frees the memory used for a geometry structure +*******************************************************************************/ +void FreeGeometry (geometry_struct *geometry) { + if (geometry != 0) { + /* Free memory used for the point structure */ + if (geometry->point != NULL) + free (geometry->point); + /* Free memory used for the elem_info vector */ + if (geometry->elem_info != 0) + free (geometry->elem_info); + /* Free memory used for the ordinates vector */ + if (geometry->ordinates != 0) + free (geometry->ordinates); + /* Free memory used for the geometry structure */ + free (geometry); + } +} + +/******************************************************************************* +** Routine: PrintGeometry +** +** Description: Print out a geometry +*******************************************************************************/ +void PrintGeometry ( + geometry_struct *geometry, + int row_number, + int print_level +) +{ + long i; + int gtype; + char *gtype_name; + int dim; + int n_elements; + int n_points; + + gtype = geometry->gtype % 1000; + dim = geometry->gtype / 1000; + n_elements = geometry->n_elem_info / 3; + n_points = geometry->n_ordinates / dim; + switch (gtype) { + case 1: + gtype_name = "POINT"; + break; + case 2: + gtype_name = "LINESTRING"; + break; + case 3: + gtype_name = "POLYGON"; + break; + case 4: + gtype_name = "COLLECTION"; + break; + case 5: + gtype_name = "MULTI-POINT"; + break; + case 6: + gtype_name = "MULTI-LINESTRING"; + break; + case 7: + gtype_name = "MULTI-POLYGON"; + break; + } + + if (print_level >= 1) { + printf ("Row %d: ", row_number); + printf ("Geometry\n"); + printf (" Type: %d (%s)\n", gtype, gtype_name); + printf (" Dimensions: %d\n", dim); + printf (" Spatial reference system: %d\n", geometry->srid); + printf (" Elements: %d\n", n_elements); + printf (" Points: %d\n", n_points); + } + + if (print_level >= 2) { + printf ("Detailed structure\n"); + printf (" SDO_GTYPE: %d\n", geometry->gtype); + printf (" SDO_SRID: %d\n", geometry->srid); + if (geometry->point != NULL) + printf (" SDO_POINT: (%f, %f, %f)\n", + geometry->point->x, geometry->point->y, geometry->point->z); + if (geometry->n_elem_info > 0) + printf (" SDO_ELEM_INFO (%d elements)\n", geometry->n_elem_info); + for (i=0; in_elem_info; i++) + printf (" [%d]=%d\n", i+1, geometry->elem_info[i]); + if (geometry->n_ordinates > 0) + printf (" SDO_ORDINATES (%d elements)\n", geometry->n_ordinates); + for (i=0; in_ordinates; i++) + printf (" [%d]=%f\n", i+1, geometry->ordinates[i]); + } +} + +/******************************************************************************* +** Routine: ReadGeometries +** +** Description: Read all geometries returned by the select statement provided +*******************************************************************************/ +void ReadGeometries ( + char *select_statement, + int print_level, + int array_size) +{ + int rows_fetched = 0; /* Row counter */ + int nr_fetches = 0; /* Number of batches fetched */ + int rows_in_batch = 0; /* Number of rows in current batch */ + boolean has_more_data; + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + int i, j, k; + + /* Define handles for host variables */ + OCIDefine *geometry_hp; + + /* Type descriptor for geometry object type */ + OCIType *geometry_type_desc; + + /* Host variables */ + SDO_GEOMETRY *geometry_obj[array_size]; + SDO_GEOMETRY_ind *geometry_ind[array_size]; + + geometry_struct *geometry; + + /* Construct the select statement */ + printf ("Executing query:\nSQL> %s\n", select_statement); + printf ("Array size: %d\n\n", array_size); + + /* Initialize array of geometry pointers */ + for (i=0; i 7) { + printf("USAGE: %s []\n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + select_statement = argv[4]; + print_level = atoi (argv[5]); + if (argc > 6) + array_size = atoi(argv[6]); + else + array_size = 10; + if (array_size <= 0) { + printf ("Invalid array size: must be positive\n"); + exit( 1 ); + } + } + + start_time = clock(); + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadGeometries(select_statement, print_level, array_size); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + + end_time = clock(); + printf("Elapsed time: %.3f seconds\n", (double) (end_time - start_time)/CLOCKS_PER_SEC); +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/read_points.c b/ProOracleSpatialCode/Code/Chapter-07/read_points.c new file mode 100644 index 0000000..6f6e076 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/read_points.c @@ -0,0 +1,327 @@ +/* read_points.c + + This program selects point objects from a table in the database. + + It reads the points without using object types, i.e by extracting + the X and Y values of each point, using the following syntax: + + SELECT C.geo_column.SDO_POINT.X, C.geo_column.SDO_POINT.Y + FROM tablename C + + It illustrates the following concepts: + - dynamically constructing SQL statements + - reading point details without using objects + + The program takes the following command line arguments: + + read_points username password database tablename geo_column + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - tablename = name of points table to select from + - geo_column = name of the geometry column to read + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadPoints +** +** Description: Read all points +*******************************************************************************/ +void ReadPoints ( + char *tablename, + char *geocolumn) +{ + int rows_fetched = 0; /* Row counter */ + char select_sql[1024]; /* SQL Statement */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + + /* Define handles for host variables */ + OCIDefine *point_x_hp; + OCIDefine *point_y_hp; + + /* Host variables */ + double point_x; + double point_y; + + /* Construct the select statement */ + sprintf (select_sql, "SELECT C.%s.SDO_POINT.X, C.%s.SDO_POINT.Y FROM %s C", geocolumn, geocolumn, tablename); + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = POINT_X (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_x_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &point_x, /* (in) Value Pointer */ + sizeof(point_x), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = POINT_Y (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_y_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + (dvoid *) &point_y, /* (in) Value Pointer */ + sizeof(point_y), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first row of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + while (status != OCI_NO_DATA) + { + /* Display results just fetched */ + rows_fetched++; + printf ("%d: (%f, %f)\n", rows_fetched, point_x, point_y); + + /* Fetch next row of result set */ + status = OCIStmtFetch( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch */ + (ub2)OCI_FETCH_NEXT, /* (in) Fetch direction */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + } + printf ("\n%d rows fetched\n", rows_fetched); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)select_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database, *tablename, *geocolumn; + + if( argc != 6) { + printf("USAGE: %s \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + tablename = argv[4]; + geocolumn = argv[5]; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadPoints(tablename, geocolumn); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/read_points_array.c b/ProOracleSpatialCode/Code/Chapter-07/read_points_array.c new file mode 100644 index 0000000..f1cf256 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/read_points_array.c @@ -0,0 +1,371 @@ +/* read_points_array.c + + This program selects point objects from a table in the database. + + It reads the points without using object types, i.e by extracting + the X and Y values of each point, using the following syntax: + + SELECT C.geo_column.SDO_POINT.X, C.geo_column.SDO_POINT.Y + FROM tablename C + + It is identical to read_points.c except that it fetches multiple rows + at a time (array fetches). + + It illustrates the following concepts: + - dynamically constructing SQL statements + - reading point details without using objects + - using array fetches + + The program takes the following command line arguments: + + read_points username password database tablename geo_column [array_size] + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - tablename = name of points table to select from + - geo_column = name of the geometry column to read + - array_size = number of rows to read per fetch (default is 10 rows) + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadPoints +** +** Description: Read all points +*******************************************************************************/ +void ReadPoints ( + char *tablename, + char *geocolumn, + int array_size) +{ + int rows_fetched = 0; /* Row counter */ + int nr_fetches = 0; /* Number of batches fetched */ + int rows_in_batch = 0; /* Number of rows in current batch */ + boolean has_more_data; + char select_sql[1024]; /* SQL Statement */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + int i, j, k; + + /* Define handles for host variables */ + OCIDefine *point_x_hp; + OCIDefine *point_y_hp; + + /* Host variables */ + double point_x[array_size]; + double point_y[array_size]; + + /* Construct the select statement */ + sprintf (select_sql, "SELECT C.%s.SDO_POINT.X, C.%s.SDO_POINT.Y FROM %s C", geocolumn, geocolumn, tablename); + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the variables to receive the selected columns */ + + /* Variable 1 = POINT_X (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_x_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &point_x, /* (in) Value Pointer */ + sizeof(double), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = POINT_Y (float) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &point_y_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + (dvoid *) &point_y, /* (in) Value Pointer */ + sizeof(double), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *)0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED) */ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first batch of rows of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)array_size, /* (in) Number of rows to fetch */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + has_more_data = TRUE; + do + { + /* Check if this is the last (or only) batch. + The Execute and Fetch calls return OCI_NO_DATA to indicate that the batch + they returned is the last one, i.e. that no further calls to OCIStmtFetch are needed. + The returned batch still needs to be processed */ + if (status == OCI_NO_DATA) + has_more_data = FALSE; + + /* Get the number of rows returned in current batch */ + OCIAttrGet( + (dvoid *)select_stmthp, + (ub4)OCI_HTYPE_STMT, + (dvoid *)&rows_in_batch, + (ub4 *)0, + (ub4)OCI_ATTR_ROWS_FETCHED, + errhp); + + nr_fetches++; + + /* Display results just fetched */ + for (i=0; i 7) { + printf("USAGE: %s []\n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + tablename = argv[4]; + geocolumn = argv[5]; + if (argc > 6) + array_size = atoi(argv[6]); + else + array_size = 10; + if (array_size <= 0) { + printf ("Invalid array size: must be positive\n"); + exit( 1 ); + } + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadPoints(tablename, geocolumn, array_size); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-07/select_pois.c b/ProOracleSpatialCode/Code/Chapter-07/select_pois.c new file mode 100644 index 0000000..527c458 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-07/select_pois.c @@ -0,0 +1,474 @@ +/* select_pois.c + + This program selects all POIs from the US_POIS table that lie within a + chosen distance from a given point. It returns the id, name and telephone + number of each POI. + + It illustrates the following concepts: + + - using null indicators for the columns returned by the select statement + - using bind variables to pass variable information to the select statement + + The program uses the following command line arguments: + + select_pois username password database poi_type x y distance unit + + where + + - username = name of the user to connect as + - password = password for that user + - database = TNS service name for the database + - poi_type = type of POI to select (from FACILITY_NAME column) + - X = longitude of search point + - Y = latitude of search point + - distance = distance to search + - unit = name of distance unit (M, KM, MILES, etc) + + Notes: + + The coordinates of the search point are assumed to be in + latitude/longitude WGS84 (srid 8307). + +*/ + +#include +#include +#include +#include + +/******************************************************************************* +** Constants +*******************************************************************************/ +#define POI_NAME_LENGTH 35 +#define PHONE_NUMBER_LENGTH 15 +#define TRACE() {printf ("TRACE: %d\n", __LINE__);} + +/******************************************************************************* +** Global variables +*******************************************************************************/ + +/* OCI handles */ + +OCIEnv *envhp; /* Environment handle*/ +OCIError *errhp; /* Error handle */ +OCISvcCtx *svchp; /* Service Context handle*/ + +/******************************************************************************* +** Routine: ReportError +** +** Description: Error message routine +*******************************************************************************/ +void ReportError(OCIError *errhp) +{ + char errbuf[512]; + sb4 errcode = 0; + + OCIErrorGet( + (dvoid *)errhp, /* (in) Error handle */ + (ub4)1, /* (in) Number of error record */ + (text *)NULL, /* (out) SQLSTATE (no longer used) */ + &errcode, /* (out) Error code */ + errbuf, /* (out) Buffer to receive error message */ + (ub4)sizeof(errbuf), /* (in) Size of error buffer */ + OCI_HTYPE_ERROR); /* (in) Type of handle (error) */ + + fprintf(stderr, "%s\n", errbuf); + exit (1); +} + +/******************************************************************************* +** Routine: InitializeOCI +** +** Description: Initialize the OCI context +*******************************************************************************/ +void InitializeOCI(void) +{ + /* Create and initialize OCI environment handle */ + OCIEnvCreate( + &envhp, /* (out) Environment Handle */ + (ub4)(OCI_DEFAULT), /* (in) Mode: default */ + (dvoid *)0, /* (in) User defined context (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined MALLOC routine (NOT USED) */ + (dvoid *(*)())0, /* (in) User-defined REALLOC routine (NOT USED) */ + (void (*)())0, /* (in) User-defined FREE routine (NOT USED) */ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (envhp == NULL) { + printf ("OCIEnvCreate: failed to create environment handle\n"); + exit (1); + } + + /* Allocate and initialize error report handle */ + OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&errhp, /* (out) Error Handle */ + (ub4)OCI_HTYPE_ERROR, /* (in) Handle type (ERROR)*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (errhp == NULL) { + printf ("OCIHandleAlloc: failed to create error handle\n"); + exit (1); + } +} +/******************************************************************************* +** Routine: ConnectDatabase +** +** Description: Connects to the oracle database +*******************************************************************************/ +void ConnectDatabase( + char *username, + char *password, + char *database) +{ + int status; + char verbuf[512]; + + /* Connect to database */ + status = OCILogon ( + envhp, /* (in) Environment Handle */ + errhp, /* (in) Error Handle */ + &svchp, /* (out) Service Context Handle */ + username, strlen(username), /* (in) Username */ + password, strlen(password), /* (in) Password */ + database, strlen(database)); /* (in) Database (TNS service name) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Get database version */ + OCIServerVersion( + svchp, /* (in) Service Context Handle */ + errhp, /* (in) Error Handle */ + verbuf, /* (out) Buffer to receive version message */ + sizeof(verbuf), /* (in) Size of message buffer */ + OCI_HTYPE_SVCCTX); /* (in) Type of handle (service context) */ + + printf("Connected to: %s\n", database); + printf("%s\n\n", verbuf); +} + +/******************************************************************************* +** Routine: DisconnectDatabase +** +** Description: Disconnect from Oracle +*******************************************************************************/ +void DisconnectDatabase(void) +{ + int status; + + status = OCILogoff(svchp, errhp); + if (status != OCI_SUCCESS) + ReportError(errhp); +} + +/******************************************************************************* +** Routine: ClearOCI +** +** Description: Release the OCI context +*******************************************************************************/ +void ClearOCI(void) +{ + /* Free error handle */ + OCIHandleFree( + (dvoid *)errhp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_ERROR); /* (in) Handle type */ + + /* Terminate OCI context */ + OCITerminate (OCI_DEFAULT); +} + +/******************************************************************************* +** Routine: ReadPois +** +** Description: Read the POIs +*******************************************************************************/ +void ReadPois ( + char *poi_type, + double x, + double y, + double distance, + char *unit) +{ + int rows_fetched = 0; /* Row counter */ + char *select_sql = + "SELECT id, poi_name, phone_number, " + "sdo_geom.sdo_distance (location, sdo_geometry(2001, 8307, sdo_point_type(:x, :y, null), null, null), 1) distance " + "from us_pois " + "where facility_name = :poi_type " + "and sdo_within_distance (location, sdo_geometry(2001, 8307, sdo_point_type(:x, :y, null), null, null), :distance_spec) = 'TRUE' " + "order by distance"; + char distance_spec[128]; /* Hold the distance specification string (DISTANCE=d UNIT=u) */ + OCIStmt *select_stmthp; /* Statement handle */ + sword status; /* OCI call return status */ + + /* Define handles for output variables */ + OCIDefine *id_hp; + OCIDefine *poi_name_hp; + OCIDefine *phone_number_hp; + + /* Bind handles for input variables */ + OCIBind *poi_type_hp = NULL; + OCIBind *x_hp = NULL; + OCIBind *y_hp = NULL; + OCIBind *distance_spec_hp = NULL; + + /* Output variables */ + long id; + char poi_name[POI_NAME_LENGTH+1]; + char phone_number[PHONE_NUMBER_LENGTH+1]; + + /* NULL indicators for output variables */ + sb2 id_ind; + sb2 poi_name_ind; + sb2 phone_number_ind; + /* NOTE: If no null indicator is provided for a column and a null value is returned then + the query fails with: ORA-01405: fetched column value is NULL */ + + /* Display the select statement */ + printf ("Executing query:\nSQL> %s\n\n", select_sql); + + /* Construct distance specifier for within_distance operator */ + sprintf (distance_spec, "distance=%f unit=%s", distance, unit); + + /* Initialize the statement handle */ + status = OCIHandleAlloc( + (dvoid *)envhp, /* (in) Environment Handle */ + (dvoid **)&select_stmthp, /* (out) Statement Handle */ + (ub4)OCI_HTYPE_STMT, /* (in) Handle type*/ + (size_t)0, /* (in) Size of extra user memory (NOT USED) */ + (dvoid **)0); /* (out) Pointer to user memory (NOT USED) */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Prepare the SQL statement */ + status = OCIStmtPrepare( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (text *)select_sql, /* (in) SQL statement */ + (ub4)strlen(select_sql), /* (in) Statement length */ + (ub4)OCI_NTV_SYNTAX, /* (in) Native SQL syntax */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Bind the input variables */ + + /* POI_TYPE (string) */ + status = OCIBindByName( + select_stmthp, /* (in) Statement Handle */ + &poi_type_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":POI_TYPE", /* (in) Placeholder */ + strlen(":POI_TYPE"), /* (in) Placeholder length */ + (ub1 *) poi_type, /* (in) Value Pointer */ + strlen(poi_type)+1, /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* X (float) */ + status = OCIBindByName( + select_stmthp, /* (in) Statement Handle */ + &x_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":X", /* (in) Placeholder */ + strlen(":X"), /* (in) Placeholder length */ + (ub1 *) &x, /* (in) Value Pointer */ + sizeof(x), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Y (float) */ + status = OCIBindByName( + select_stmthp, /* (in) Statement Handle */ + &y_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":Y", /* (in) Placeholder */ + strlen(":Y"), /* (in) Placeholder length */ + (ub1 *) &y, /* (in) Value Pointer */ + sizeof(y), /* (in) Value Size */ + SQLT_FLT, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* DISTANCE_SPEC (string) */ + status = OCIBindByName( + select_stmthp, /* (in) Statement Handle */ + &distance_spec_hp, /* (out) Bind Handle */ + errhp, /* (in) Error Handle */ + (text *) ":DISTANCE_SPEC", /* (in) Placeholder */ + strlen(":DISTANCE_SPEC"), /* (in) Placeholder length */ + (ub1 *) distance_spec, /* (in) Value Pointer */ + sizeof(distance_spec), /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *) 0, /* (in) Indicator Pointer (NOT USED) */ + (ub2 *) 0, /* (out) Actual length (NOT USED) */ + (ub2) 0, /* (out) Column return codes (NOT USED) */ + (ub4) 0, /* (in) (NOT USED) */ + (ub4 *) 0, /* (in) (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Define the output variables to receive the selected columns */ + + /* Variable 1 = ID (integer) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &id_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Bind variable position */ + (dvoid *) &id, /* (in) Value Pointer */ + sizeof(id), /* (in) Value Size */ + SQLT_INT, /* (in) Data Type */ + (dvoid *) &id_ind, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 2 = POI_NAME (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &poi_name_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)2, /* (in) Bind variable position */ + (dvoid *) &poi_name, /* (in) Value Pointer */ + sizeof(poi_name), /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *) &poi_name_ind, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Variable 3 = PHONE_NUMBER (string) */ + status = OCIDefineByPos( + select_stmthp, /* (in) Statement Handle */ + &phone_number_hp, /* (out) Define Handle */ + errhp, /* (in) Error Handle */ + (ub4)3, /* (in) Bind variable position */ + (dvoid *) &phone_number, /* (in) Value Pointer */ + sizeof(phone_number), /* (in) Value Size */ + SQLT_STR, /* (in) Data Type */ + (dvoid *) &phone_number_ind, /* (in) Indicator Pointer */ + (ub2 *)0, /* (out) Length of data fetched (NOT USED)*/ + (ub2 *)0, /* (out) Column return codes (NOT USED) */ + (ub4)OCI_DEFAULT /* (in) Operating mode */ + ); + if (status != OCI_SUCCESS) + ReportError(errhp); + + /* Execute query and fetch first row of result set */ + status = OCIStmtExecute( + svchp, /* (in) Service Context Handle */ + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch: 1 */ + (ub4)0, /* (in) Row offset (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot in (NOT USED) */ + (OCISnapshot *)NULL, /* (in) Snapshot out (NOT USED) */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + + while (status != OCI_NO_DATA) + { + /* Display results just fetched */ + rows_fetched++; + + /* Consider that PHONE_NUMBER could be null.*/ + if (phone_number_ind == OCI_IND_NULL) + strcpy ( phone_number, "NO TELEPHONE"); + + printf ("%d: %d %*s %s\n", rows_fetched, id, POI_NAME_LENGTH, poi_name, phone_number); + + /* Fetch next row of result set */ + status = OCIStmtFetch( + select_stmthp, /* (in) Statement Handle */ + errhp, /* (in) Error Handle */ + (ub4)1, /* (in) Number of rows to fetch */ + (ub2)OCI_FETCH_NEXT, /* (in) Fetch direction */ + (ub4)OCI_DEFAULT); /* (in) Operating mode */ + if (status != OCI_SUCCESS && status != OCI_NO_DATA) + ReportError(errhp); + } + printf ("\n%d rows fetched\n", rows_fetched); + + /* Free statement handle */ + status = OCIHandleFree( + (dvoid *)select_stmthp, /* (in) Statement Handle */ + (ub4)OCI_HTYPE_STMT); /* (in) Handle type */ + if (status != OCI_SUCCESS) + ReportError(errhp); + +} + +/******************************************************************************* +** Routine: Main +** +** Description: Program main +*******************************************************************************/ +int main(int argc, char **argv) +{ + char *username, *password, *database, *poi_type, *unit; + double x, y, distance; + int i; + + if( argc != 9) { + printf("USAGE: %s \n", argv[0]); + exit( 1 ); + } + else { + username = argv[1]; + password = argv[2]; + database = argv[3]; + poi_type = argv[4]; + sscanf(argv[5], "%lf", &x); + sscanf(argv[6], "%lf", &y); + sscanf(argv[7], "%lf", &distance); + unit = argv[8]; + } + + /* Set up OCI environment */ + InitializeOCI(); + + /* Connect to database */ + ConnectDatabase(username, password, database); + + /* Fetch and process the records */ + ReadPois(poi_type, x, y, distance, unit); + + /* disconnect from database */ + DisconnectDatabase(); + + /* Teardown OCI environment */ + ClearOCI(); + +} diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-01.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-01.sql new file mode 100644 index 0000000..65f9ac7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-01.sql @@ -0,0 +1,6 @@ +-- Listing 8-1. SDO_WITHIN_DISTANCE Spatial Operator in SQL +SELECT COUNT(*) +FROM branches b , customers c +WHERE b.id=1 + AND SDO_WITHIN_DISTANCE + (c.location, b.location, 'DISTANCE=0.5 UNIT=MILE')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-02.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-02.sql new file mode 100644 index 0000000..3832c17 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-02.sql @@ -0,0 +1,3 @@ +-- Listing 8-2. Creating an Index +CREATE INDEX customers_spatial_idx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-03.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-03.sql new file mode 100644 index 0000000..0311d70 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-03.sql @@ -0,0 +1,2 @@ +-- Listing 8-3. USER_SDO_GEOM_METADATA View +DESCRIBE USER_SDO_GEOM_METADATA; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-04.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-04.sql new file mode 100644 index 0000000..17328c8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-04.sql @@ -0,0 +1,26 @@ +-- Listing 8-4. Inserting Metadata for the Spatial Layer Corresponding to the location Column of the customers Table +INSERT INTO user_sdo_geom_metadata +(table_name, column_name, srid, diminfo) +VALUES +( + 'CUSTOMERS', -- TABLE_NAME + 'LOCATION', -- COLUMN_NAME + 8307, -- SRID specifying a geodetic coordinate system + SDO_DIM_ARRAY -- DIMINFO attribute for storing dimension bounds, tolerance + ( + SDO_DIM_ELEMENT + ( + 'LONGITUDE', -- DIMENSION NAME for first dimension + -180, -- SDO_LB for the dimension: -180 degrees + 180, -- SDO_UB for the dimension: 180 degrees + 0.5 -- Tolerance of 0.5 meters (not 0.5 degrees: geodetic SRID) + ), + SDO_DIM_ELEMENT + ( + 'LATITUDE', -- DIMENSION NAME for second dimension + -90, -- SDO_LB for the dimension: -90 degrees + 90, -- SDO_UB for the dimension: 90 degrees + 0.5 -- Tolerance of 0.5 meters (not 0.5 degrees: geodetic SRID) + ) + ) +); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-05.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-05.sql new file mode 100644 index 0000000..ba9ac5b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-05.sql @@ -0,0 +1,2 @@ +-- Listing 8-5. Dropping a Spatial Index +DROP INDEX customers_sidx; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-06.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-06.sql new file mode 100644 index 0000000..f6c9c87 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-06.sql @@ -0,0 +1,3 @@ +-- Listing 8-6. Creating a Spatial Index on the location Column of the customers Table +CREATE INDEX customers_spatial_idx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-07.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-07.sql new file mode 100644 index 0000000..680c2e3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-07.sql @@ -0,0 +1,3 @@ +-- Listing 8-7. Identifying the SDO_INDEX_TABLE That Stores the Spatial Index on the customers Table +SELECT SDO_INDEX_TABLE FROM USER_SDO_INDEX_INFO +WHERE TABLE_NAME = 'CUSTOMERS' AND COLUMN_NAME='LOCATION'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-09.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-09.sql new file mode 100644 index 0000000..a09d165 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-09.sql @@ -0,0 +1,4 @@ +-- Listing 8-9. Creating a Spatial Index in Tablespace TBS_3 +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('TABLESPACE=TBS_3'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-10.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-10.sql new file mode 100644 index 0000000..d3aee32 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-10.sql @@ -0,0 +1,4 @@ +-- Listing 8-10. Creating an Index with the INITIAL and NEXT Extents for an Index Table +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('TABLESPACE=TBS_3 NEXT=5K INITIAL=10K'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-11.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-11.sql new file mode 100644 index 0000000..893db9e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-11.sql @@ -0,0 +1,4 @@ +-- Listing 8-11. Creating an Index with WORK_TABLESPACE As TBS_3 +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('WORK_TABLESPACE=TBS_3'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-12.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-12.sql new file mode 100644 index 0000000..e546dfb --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-12.sql @@ -0,0 +1,4 @@ +-- Listing 8-12. Creating an Index for Specific-Type (Point) Geometries +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('LAYER_GTYPE=POINT'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-13.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-13.sql new file mode 100644 index 0000000..baeeb0b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-13.sql @@ -0,0 +1,4 @@ +-- Listing 8-13. Creating an R-tree Index with Dimensionality Specified +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('SDO_INDX_DIMS=2'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-14.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-14.sql new file mode 100644 index 0000000..cc4482c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-14.sql @@ -0,0 +1,4 @@ +-- Listing 8-14. Creating an Index with the SDO_DML_BATCH_SIZE Parameter +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('SDO_DML_BATCH_SIZE=5000'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-15.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-15.sql new file mode 100644 index 0000000..3325298 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-15.sql @@ -0,0 +1,4 @@ +-- Listing 8-15. Creating a Quadtree Type of Spatial Index +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('SDO_LEVEL=8'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-16.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-16.sql new file mode 100644 index 0000000..19e1080 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-16.sql @@ -0,0 +1,4 @@ +-- Listing 8-16. Examining the USER_SDO_INDEX_METADATAView for Index Parameters +SELECT SDO_DML_BATCH_SIZE +FROM USER_SDO_INDEX_METADATA +WHERE SDO_INDEX_NAME = 'CUSTOMERS_SIDX'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-17.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-17.sql new file mode 100644 index 0000000..c6a4607 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-17.sql @@ -0,0 +1,8 @@ +-- Listing 8-17. Estimating the Size of a Spatial Index on the location Column of the customers Table +SELECT sdo_tune.estimate_rtree_index_size +( + 'SPATIAL', -- schema name + 'CUSTOMERS', -- table name + 'LOCATION' -- column name on which the spatial index is to be built +) sz +FROM dual; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-19.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-19.sql new file mode 100644 index 0000000..60c8073 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-19.sql @@ -0,0 +1,6 @@ +-- Listing 8-19. Spatial Operator Usage in a SQL Statement +SELECT COUNT(*) +FROM branches b, customers c +WHERE b.id=1 +AND SDO_WITHIN_DISTANCE + (c.location, b.location, 'DISTANCE=0.5 UNIT=MILE') = 'TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-20.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-20.sql new file mode 100644 index 0000000..9051029 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-20.sql @@ -0,0 +1,7 @@ +-- Listing 8-20. SDO_WITHIN_DISTANCE Operator Retrieving All Customers Within a Quarter-Mile Radius of a Competitor Store +SELECT ct.id, ct.name +FROM competitors comp, customers ct +WHERE comp.id=1 +AND SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'DISTANCE=0.25 UNIT=MILE ' )='TRUE' +ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-21.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-21.sql new file mode 100644 index 0000000..0343bd8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-21.sql @@ -0,0 +1,9 @@ +-- Listing 8-21. SDO_WITHIN_DISTANCE Operator Retrieving All Customers in a Quarter-Mile Radius of a Competitor Store and Also Reporting Their Distances +col dist format 999 +SELECT ct.id, ct.name, + SDO_GEOM.SDO_DISTANCE(ct.location, comp.location, 0.5, ' UNIT=YARD ') dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'DISTANCE=0.25 UNIT=MILE' )='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-22.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-22.sql new file mode 100644 index 0000000..60975df --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-22.sql @@ -0,0 +1,5 @@ +-- Listing 8-22. A Simple Example of the SDO_NN Operator +SELECT ct.id, ct.name + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN(ct.location, comp.location)='TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-23.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-23.sql new file mode 100644 index 0000000..5f16394 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-23.sql @@ -0,0 +1,7 @@ +-- Listing 8-23. SDO_NN Operator Retrieving the Five Nearest Customers to a Specific Competitor +SELECT ct.id, ct.name, ct.customer_grade + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN(ct.location, comp.location)='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-24.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-24.sql new file mode 100644 index 0000000..39ed12d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-24.sql @@ -0,0 +1,8 @@ +-- Listing 8-24. SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitor +SELECT ct.id, ct.name, ct.customer_grade + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location)='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-25.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-25.sql new file mode 100644 index 0000000..ef26e99 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-25.sql @@ -0,0 +1,8 @@ +-- Listing 8-25. SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Competitor +SELECT ct.id, ct.name, ct.customer_grade + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location, 'SDO_BATCH_SIZE=100' )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-26.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-26.sql new file mode 100644 index 0000000..9cd844f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-26.sql @@ -0,0 +1,5 @@ +-- Listing 8-26. SDO_NN Operator Retrieving the Five Customers Nearest to a Specific Competitor +SELECT ct.id, ct.name, ct.customer_grade + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN(ct.location, comp.location, 'SDO_NUM_RES=5')='TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-27.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-27.sql new file mode 100644 index 0000000..dccd506 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-27.sql @@ -0,0 +1,7 @@ +-- Listing 8-27. SDO_NN Operator Retrieving the Five Customers Nearest to a Specific Competitor Along with Their Distances +col dist format 999 +SELECT ct.id, ct.name, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN(ct.location, comp.location, 'SDO_NUM_RES=5',1)='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-28.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-28.sql new file mode 100644 index 0000000..8b8301b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-28.sql @@ -0,0 +1,8 @@ +-- Listing 8-28. SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitor Along with Their Distances +SELECT ct.id, ct.name, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location, 'SDO_BATCH_SIZE=100', 1 )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-29.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-29.sql new file mode 100644 index 0000000..959e4db --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-29.sql @@ -0,0 +1,7 @@ +-- Listing 8-29. Rewriting Listing 8-27 with Mile As the Distance Unit +col dist format 9.99 +SELECT ct.id, ct.name, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN(ct.location, comp.location, 'SDO_NUM_RES=5 UNIT=MILE',1)='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-30.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-30.sql new file mode 100644 index 0000000..30a1d67 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-30.sql @@ -0,0 +1,10 @@ +-- Listing 8-30. Rewriting Listing 8-28 with Mile As the Distance Unit +col dist format 9.99 +SELECT ct.id, ct.name, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN + (ct.location, comp.location, 'SDO_BATCH_SIZE=100 UNIT=MILE', 1 )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-31.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-31.sql new file mode 100644 index 0000000..8612246 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-31.sql @@ -0,0 +1,9 @@ +-- Listing 8-31. Creating the Sales Region (Area of Influence) for Each Competitor/Branch + +CREATE TABLE COMPETITORS_SALES_REGIONS AS + SELECT id, name, SDO_GEOM.SDO_BUFFER (a.location, 0.25, 0.5, 'UNIT=MILE ARC_TOLERANCE=0.005') geom + FROM competitors a; + +CREATE TABLE SALES_REGIONS AS + SELECT id, name, SDO_GEOM.SDO_BUFFER (a.location, 0.25, 0.5, 'UNIT=MILE ARC_TOLERANCE=0.005') geom + FROM branches a; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-32.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-32.sql new file mode 100644 index 0000000..3375596 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-32.sql @@ -0,0 +1,20 @@ +-- Listing 8-32. Creating Indexes on Sales Regions of Competitors/Branches +Rem Metadata for Sales_regions table +INSERT INTO USER_SDO_GEOM_METADATA + SELECT 'SALES_REGIONS','GEOM', DIMINFO, SRID + FROM USER_SDO_GEOM_METADATA + WHERE TABLE_NAME='BRANCHES'; + +Rem Metadata for Competitors_regions table +INSERT INTO USER_SDO_GEOM_METADATA + SELECT 'COMPETITORS_SALES_REGIONS','GEOM', DIMINFO, SRID + FROM USER_SDO_GEOM_METADATA + WHERE TABLE_NAME='COMPETITORS'; + +Rem Index-creation for Sales_regions table +CREATE INDEX sr_sidx ON sales_regions(geom) + INDEXTYPE IS MDSYS.SPATIAL_INDEX; + +Rem Index-creation for Competitors_sales_regions table +CREATE INDEX cr_sidx ON competitors_sales_regions(geom) + INDEXTYPE IS MDSYS.SPATIAL_INDEX; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-33.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-33.sql new file mode 100644 index 0000000..fd75406 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-33.sql @@ -0,0 +1,6 @@ +-- Listing 8-33. SDO_FILTER Operator Retrieving All Customers Within a Competitor’s Service Area +SELECT ct.id, ct.name + FROM competitors_regions comp, customers ct + WHERE comp.id=1 + AND SDO_FILTER(ct.location, comp.geom)='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-34.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-34.sql new file mode 100644 index 0000000..6ebaf2d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-34.sql @@ -0,0 +1,13 @@ +-- Listing 8-34. Typical Query from MapViewer Using the SDO_FILTER Operator +SELECT location +FROM customers +WHERE SDO_FILTER + ( + location, + SDO_GEOMETRY + ( + 2003, 8307, null, + SDO_ELEM_INFO_ARRAY(1, 1003, 3), -- Rectangle query window + SDO_ORDINATE_ARRAY(-122.43886,37.78284,-122.427195,37.79284) + ) + ) = 'TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-35.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-35.sql new file mode 100644 index 0000000..f848e7d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-35.sql @@ -0,0 +1,6 @@ +-- Listing 8-35. SDO_RELATE Operator Retrieving All Customers in a Quarter-Mile Buffer Zone of a Competitor Store +SELECT ct.id, ct.name + FROM competitors_sales_regions comp, customers ct + WHERE comp.id=1 + AND SDO_RELATE(ct.location, comp.geom, 'MASK=ANYINTERACT ' )='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-36.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-36.sql new file mode 100644 index 0000000..a3607d3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-36.sql @@ -0,0 +1,10 @@ +-- Listing 8-36. Identifying a DISJOINT relationship +SELECT ct.id, ct.name + FROM customers ct + WHERE ct.rowid NOT IN +( + SELECT ct.rowid + FROM competitors_sales_regions comp, customers ct + WHERE comp.id=1 + AND SDO_RELATE(ct.location, comp.geom, 'MASK=ANYINTERACT')='TRUE' +); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-37.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-37.sql new file mode 100644 index 0000000..1c147f7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-37.sql @@ -0,0 +1,5 @@ +-- Listing 8-37. SDO_RELATE Operator Identifying All Competitors in the D.C. Region +SELECT COUNT(*) + FROM us_states st, competitors_sales_regions comp + WHERE st.state_abrv='DC' + AND SDO_RELATE(comp.geom, st.geom, 'MASK=ANYINTERACT') ='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-38.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-38.sql new file mode 100644 index 0000000..23db8d3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-38.sql @@ -0,0 +1,5 @@ +-- Listing 8-38. SDO_RELATE Operator Identifying All Competitors Inside the D.C. Region +SELECT COUNT(*) + FROM us_states st, competitors_sales_regions comp + WHERE st.state_abrv='DC' + AND SDO_RELATE(comp.geom, st.geom, 'MASK=INSIDE') = 'TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-39.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-39.sql new file mode 100644 index 0000000..550b6cd --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-39.sql @@ -0,0 +1,5 @@ +-- Listing 8-39. SDO_RELATE Operator Identifying All Competitors That Overlap the D.C. Region +SELECT COUNT(*) + FROM us_states st, competitors_sales_regions comp + WHERE st.state_abrv='DC' + AND SDO_RELATE(comp.geom, st.geom, 'MASK=OVERLAPBDYINTERSECT') = 'TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-40.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-40.sql new file mode 100644 index 0000000..7d92e28 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-40.sql @@ -0,0 +1,6 @@ +-- Listing 8-40. Identifying Sales Regions That Intersect a Specific Sales Region (id=51) +SELECT a.id + FROM sales_regions b, sales_regions a + WHERE b.id=51 + AND a.id <> 51 + AND SDO_RELATE(a.geom, b.geom, 'MASK=ANYINTERACT') = 'TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-41.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-41.sql new file mode 100644 index 0000000..c224141 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-41.sql @@ -0,0 +1,7 @@ +-- Listing 8-41. Identifying All Sales Regions That Overlap a Specific Sales Region (id=51) +SELECT a.id + FROM sales_regions b, sales_regions a + WHERE b.id=51 + AND a.id <> 51 + AND SDO_RELATE + (a.geom, b.geom, 'MASK=OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT')='TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-42.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-42.sql new file mode 100644 index 0000000..7ea2e70 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-42.sql @@ -0,0 +1,6 @@ +-- Listing 8-42. Verifying That a Sales Region Touches Another Sales Region (id=51) +SELECT a.id + FROM sales_regions b, sales_regions a + WHERE b.id=51 + AND a.id <> 51 + AND SDO_RELATE(a.geom, b.geom, 'MASK=TOUCH') = 'TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-43.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-43.sql new file mode 100644 index 0000000..d0d34fc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-43.sql @@ -0,0 +1,5 @@ +-- Listing 8-43. Adding the SDO_LEVEL=6 Parameter to an SDO_RELATE Query +SELECT COUNT(*) + FROM us_states st, competitors_sales_regions comp + WHERE st.state_abrv='DC' + AND SDO_RELATE(comp.geom, st.geom, 'MASK=INSIDE SDO_LEVEL=6') = 'TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-44.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-44.sql new file mode 100644 index 0000000..2db7c3e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-44.sql @@ -0,0 +1,11 @@ +-- Listing 8-44. Explaining the Execution Plan for a SQL Statement +@$ORACLE_HOME/rdbms/admin/utlxplan -- Load only once +SET AUTOTRACE ON +SELECT ct.id + FROM customers ct + WHERE SDO_WITHIN_DISTANCE + ( + ct.location, + (SELECT location FROM competitors WHERE id=1), + 'DISTANCE=0.25 UNIT=MILE' +)='TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-45.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-45.sql new file mode 100644 index 0000000..829ea27 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-45.sql @@ -0,0 +1,9 @@ +-- Listing 8-45. SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitor Along with Their Distances +col dist format 9999 +SELECT ct.id, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location, 'SDO_BATCH_SIZE=100', 1 )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-46.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-46.sql new file mode 100644 index 0000000..cc20796 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-46.sql @@ -0,0 +1,13 @@ +-- Listing 8-46. Creating an Index on customer_grade and Rerunning Listing 8-45 + +CREATE INDEX cust_grade ON customers(customer_grade); + +col dist format 9999 + +SELECT ct.id, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location, 'SDO_BATCH_SIZE=100', 1 )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-47.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-47.sql new file mode 100644 index 0000000..b5aa3fa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-47.sql @@ -0,0 +1,9 @@ +-- Listing 8-47. Usage of Hints with SDO_NN and Other Operators on the Same Table +SELECT /*+ NO_INDEX(ct cust_grade) INDEX(ct customers_sidx) */ + ct.id, ct.customer_grade, SDO_NN_DISTANCE(1) dist + FROM competitors comp, customers ct + WHERE comp.id=1 + AND ct.customer_grade='GOLD' + AND SDO_NN(ct.location, comp.location, 'SDO_BATCH_SIZE=100', 1 )='TRUE' + AND ROWNUM<=5 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-48.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-48.sql new file mode 100644 index 0000000..dcc603b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-48.sql @@ -0,0 +1,7 @@ +-- Listing 8-48. Spatial Operator with Multiple Hints in a SQL Statement with Two Tables +SELECT /*+ ORDERED */ ct.id, ct.name + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'DISTANCE=0.25 UNIT=MILE') = 'TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-49.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-49.sql new file mode 100644 index 0000000..f669cb7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-49.sql @@ -0,0 +1,18 @@ +-- Listing 8-49. Creating a Deterministic Function to Return an SDO_GEOMETRYUsing Address Attributes of the customers Table +CREATE or REPLACE FUNCTION gcdr_geometry( + street_number varchar2, + street_name varchar2, + city varchar2, + state varchar2, + postal_code varchar2) +RETURN MDSYS.SDO_GEOMETRY DETERMINISTIC is +BEGIN +RETURN (sdo_gcdr.geocode_as_geometry( + 'SPATIAL', + sdo_keywordarray( + street_number || ' ' ||street_name , + city || ' ' || state || ' ' || postal_code), + 'US') + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-50.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-50.sql new file mode 100644 index 0000000..f432273 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-50.sql @@ -0,0 +1,4 @@ +-- Listing 8-50. Declaring the gcdr_geometry Function As DETERMINISTIC +SELECT gcdr_geometry(street_number,street_name,city,state,postal_code).sdo_point.x x, + gcdr_geometry(street_number,street_name,city,state,postal_code).sdo_point.y y + FROM customers WHERE id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-51.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-51.sql new file mode 100644 index 0000000..0ded5f7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-51.sql @@ -0,0 +1,12 @@ +-- Listing 8-51. Inserting the Metadata for a +INSERT INTO user_sdo_geom_metadata VALUES +( + 'CUSTOMERS', + 'SPATIAL.GCDR_GEOMETRY(street_number,street_name,city,state,postal_code)', + SDO_DIM_ARRAY + ( + SDO_DIM_ELEMENT('X', -180, 180, 0.5), + SDO_DIM_ELEMENT('Y', -90, 90, 0.5) + ), + 8307 +); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-52.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-52.sql new file mode 100644 index 0000000..6bf3cf4 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-52.sql @@ -0,0 +1,7 @@ +-- Listing 8-52. Creating a Spatial Index on a Function Returning an SDO_GEOMETRY +CREATE INDEX customers_spatial_fun_idx ON customers + ( + gcdr_geometry(street_number, street_name, city, state, postal_code) + ) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('LAYER_GTYPE=POINT'); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-53.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-53.sql new file mode 100644 index 0000000..30bde45 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-53.sql @@ -0,0 +1,3 @@ +-- Listing 8-53. Setting Session Parameters to Enable Query Rewrite on Function-Based Indexes +ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED; +ALTER SESSION SET QUERY_REWRITE_ENABLED = TRUE; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-54.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-54.sql new file mode 100644 index 0000000..778e062 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-54.sql @@ -0,0 +1,12 @@ +-- Listing 8-54. SDO_NN Operator Retrieving the Five Customers Nearest to Each Competitor Using the Function-Based Index +SELECT /*+ ORDERED */ ct.id, ct.name, ct.customer_grade + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_NN + ( + gcdr_geometry + (ct.street_number,ct.street_name, ct.city, ct.state, ct.postal_code), + comp.location, + 'SDO_NUM_RES=5' + )='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-55.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-55.sql new file mode 100644 index 0000000..60a9223 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-55.sql @@ -0,0 +1,19 @@ +-- Listing 8-55. Creating a Partitioned Table +CREATE TABLE customers +( + NAME VARCHAR2(64), + ID NUMBER, + STREET_NUMBER VARCHAR2(14), + STREET_NAME VARCHAR2(80), + CITY VARCHAR2(64), + STATE VARCHAR2(64), + POSTAL_CODE VARCHAR2(16), + CUSTOMER_GRADE VARCHAR2(15), + LOCATION SDO_GEOMETRY +) +PARTITION by RANGE(CUSTOMER_GRADE) +( + PARTITION GOLD VALUES LESS THAN ('GOLDZZZZZZ'), + PARTITION PLATINUM VALUES LESS THAN ('PLATINUMZZZZZZ'), + PARTITION SILVER VALUES LESS THAN ('SILVERZZZZZZ') +); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-57.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-57.sql new file mode 100644 index 0000000..7e4c716 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-57.sql @@ -0,0 +1,10 @@ +-- Listing 8-57. Creating a Local Partitioned Spatial Index with Partition-Specific Parameters +CREATE INDEX customers_spatial_idx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS ('TABLESPACE=USERS') + LOCAL + ( + PARTITION IP1 PARAMETERS('TABLESPACE=TBS_3'), + PARTITION IP2, + PARTITION IP3 + ); diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-58.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-58.sql new file mode 100644 index 0000000..b925a10 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-58.sql @@ -0,0 +1,8 @@ +-- Listing 8-58. SDO_WITHIN_DISTANCE Operator on a Partitioned Table +SELECT /*+ ORDERED */ ct.id, ct.name + FROM competitors comp, customers ct + WHERE comp.id=1 + AND customer_grade='GOLD' + AND SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'DISTANCE=0.25 UNIT=MILE ' )='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-59.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-59.sql new file mode 100644 index 0000000..55546ae --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-59.sql @@ -0,0 +1,10 @@ +-- Listing 8-59. Obtaining the Five Customers Nearest to Each Competitor When the customers Table Has a Local Partitioned Index +SELECT id, name FROM +( + SELECT /*+ ORDERED */ a.id , a.name, SDO_NN_DISTANCE(1) dist + FROM competitors b, customers a + WHERE b.id=1 + AND SDO_NN(a.location, b.location, 'SDO_NUM_RES=5' , 1)='TRUE' ORDER BY dist +) +WHERE ROWNUM<=5 +ORDER BY id; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-61.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-61.sql new file mode 100644 index 0000000..38db958 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-61.sql @@ -0,0 +1,2 @@ +-- Listing 8-61. Setting the Degree of Parallelism to 2 for a Table +ALTER TABLE customers PARALLEL 2 ; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-62.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-62.sql new file mode 100644 index 0000000..005905a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-62.sql @@ -0,0 +1,5 @@ +-- Listing 8-62. SDO_RELATE Operator Retrieving All Customers Inside (and Touching the Border of) Each Competitor Region +SELECT COUNT(DISTINCT ct.id) + FROM competitors comp, customers ct + WHERE SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'DISTANCE=200 UNIT=METER ' )='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-63.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-63.sql new file mode 100644 index 0000000..9418833 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-63.sql @@ -0,0 +1,14 @@ +-- Listing 8-63. SDO_JOIN Operator Analyzing the Number of Customers Inside All the Competitor Regions +SELECT COUNT(DISTINCT ct.id) + FROM competitors comp, customers ct, + TABLE + ( + SDO_JOIN + ( + 'COMPETITORS', 'LOCATION', -- first table and the SDO_GEOMETRY column + 'CUSTOMERS', 'LOCATION', -- second table and the SDO_GEOMETRY column + 'DISTANCE=200 UNIT=METER' -- specify mask relationship + ) + ) jn + WHERE ct.rowid=jn.rowid2 + AND comp.rowid = jn.rowid1; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-64.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-64.sql new file mode 100644 index 0000000..077e5b2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-64.sql @@ -0,0 +1,4 @@ +-- Listing 8-64. SDO_FILTER Operator Retrieving All Customers Whose MBRs Intersect Those of Competitor Regions +SELECT COUNT(DISTINCT ct.id) + FROM competitors_sales_regions comp, customers ct + WHERE SDO_FILTER(ct.location, comp.geom)='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-08/listing-08-65.sql b/ProOracleSpatialCode/Code/Chapter-08/listing-08-65.sql new file mode 100644 index 0000000..e098325 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-08/listing-08-65.sql @@ -0,0 +1,13 @@ +-- Listing 8-65. SDO_JOIN Operator Retrieving All Customers Whose MBRs Intersect the MBRs of Competitor Regions (Filter Operation Is Used) +SELECT COUNT(DISTINCT ct.id) + FROM competitors_sales_regions comp, customers ct, + TABLE + ( + SDO_JOIN + ( + 'COMPETITORS_SALES_REGIONS', 'GEOM', -- first table and column + 'CUSTOMERS', 'LOCATION' -- second table and column + ) + ) jn + WHERE ct.rowid=jn.rowid2 + AND comp.rowid = jn.rowid1; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-01.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-01.sql new file mode 100644 index 0000000..6854f54 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-01.sql @@ -0,0 +1,5 @@ +-- Listing 9-1. Creating Buffers Around Branches +CREATE TABLE sales_regions AS + SELECT id, + SDO_GEOM.SDO_BUFFER(a.location, 0.25, 0.5, 'arc_tolerance=0.005 unit=mile') geom + FROM branches a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-02.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-02.sql new file mode 100644 index 0000000..14051aa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-02.sql @@ -0,0 +1,5 @@ +-- Listing 9-2. Creating Buffers Around Competitor Locations +CREATE TABLE COMPETITORS_SALES_REGIONS AS + SELECT id, + SDO_GEOM.SDO_BUFFER(a.location, 0.25, 0.5, 'unit=mile arc_tolerance=0.005') geom + FROM competitors a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-03.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-03.sql new file mode 100644 index 0000000..e4fa1c8 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-03.sql @@ -0,0 +1,6 @@ +-- Listing 9-3. Identifying Customers Within a Quarter-Mile of a Competitor Location +SELECT ct.id, ct.name + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_GEOM.SDO_DISTANCE(ct.location, comp.location, 0.5, 'unit=mile') < 0.25 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-04.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-04.sql new file mode 100644 index 0000000..e78351b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-04.sql @@ -0,0 +1,8 @@ +-- Listing 9-4. Using the SDO_DISTANCE Function with the SDO_WITHIN_DISTANCE Spatial Operator in SQL +SELECT ct.id, ct.name, + SDO_GEOM.SDO_DISTANCE(ct.location, comp.location, 0.5, 'unit=yard') distance + FROM competitors comp, customers ct + WHERE comp.id=1 + AND SDO_WITHIN_DISTANCE + (ct.location, comp.location, 'distance=0.25 unit=mile')='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-05.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-05.sql new file mode 100644 index 0000000..d9a4ff0 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-05.sql @@ -0,0 +1,6 @@ +-- Listing 9-5. Identifying Customers Inside a Competitor’s Sales Region +SELECT ct.id, ct.name + FROM customers ct, competitors_sales_regions comp + WHERE SDO_GEOM.RELATE (ct.location, 'INSIDE', comp.geom, 0.1) = 'INSIDE' + AND comp.id=1 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-06.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-06.sql new file mode 100644 index 0000000..389da0a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-06.sql @@ -0,0 +1,6 @@ +-- Listing 9-6. Identifying Customers That Interact with a Competitor’s Sales Region +SELECT ct.id, ct.name + FROM customers ct, competitors_sales_regions comp + WHERE SDO_GEOM.RELATE (ct.location, 'ANYINTERACT', comp.geom, 0.5) = 'TRUE' + AND comp.id=1 + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-07.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-07.sql new file mode 100644 index 0000000..000b0a0 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-07.sql @@ -0,0 +1,5 @@ +-- Listing 9-7. Identifying Suppliers in a Quarter-Mile Buffer Around a Competitor +SELECT a.id + FROM suppliers a, competitors_sales_regions b + WHERE SDO_GEOM.RELATE (a.location, 'ANYINTERACT', b.geom, 0.5) = 'TRUE' + AND b.id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-08.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-08.sql new file mode 100644 index 0000000..f3d546a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-08.sql @@ -0,0 +1,7 @@ +-- Listing 9-8. Identifying Customers in Quarter-Mile Buffer Around a Competitor +col relationship for a20 +SELECT ct.id, ct.name, + SDO_GEOM.RELATE (ct.location, 'DETERMINE', comp.geom, 0.5) relationship + FROM customers ct, competitors_sales_regions comp + WHERE comp.id=1 + AND SDO_RELATE(ct.location, comp.geom, 'mask=anyinteract')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-09.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-09.sql new file mode 100644 index 0000000..c90c170 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-09.sql @@ -0,0 +1,13 @@ +-- Listing 9-9. RELATE Function Complementing the SDO_RELATE Operator +SELECT a.id, + SDO_GEOM.RELATE(a.geom, 'DETERMINE', b.geom, 0.5) relationship + FROM sales_regions b, sales_regions a + WHERE b.id=51 + AND a.id<>51 + AND SDO_RELATE + ( + a.geom, + b.geom, + 'mask=TOUCH+OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT' + ) = 'TRUE' + ORDER BY a.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-10.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-10.sql new file mode 100644 index 0000000..0357146 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-10.sql @@ -0,0 +1,7 @@ +-- Listing 9-10. SDO_INTERSECTION of Two Geometries +CREATE TABLE sales_intersection_zones AS + SELECT a.id id1, b.id id2, + SDO_GEOM.SDO_INTERSECTION(a.geom, b.geom, 0.5) intsxn_geom + FROM sales_regions b, sales_regions a + WHERE a.id<> b.id + AND SDO_RELATE(a.geom, b.geom, 'mask=anyinteract') = 'TRUE' ; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-11.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-11.sql new file mode 100644 index 0000000..d8a4e60 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-11.sql @@ -0,0 +1,4 @@ +-- Listing 9-11. Sales Regions Intersecting the Sales Region with id=51 +SELECT id2 + FROM sales_intersection_zones + WHERE id1=51; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-12.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-12.sql new file mode 100644 index 0000000..537b74f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-12.sql @@ -0,0 +1,5 @@ +-- Listing 9-12. Identifying Customers in sales_ intersection_zones +SELECT count(*) + FROM sales_intersection_zones b, customers a + WHERE b.id1=51 AND b.id2=43 + AND SDO_RELATE(a.location, b.intsxn_geom, 'mask=anyinteract')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-13.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-13.sql new file mode 100644 index 0000000..220fd5c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-13.sql @@ -0,0 +1,13 @@ +-- Listing 9-13. Identifying Customers in the Intersection of Sales Regions 51 and 43 +SELECT COUNT(*) + FROM customers ct + WHERE SDO_RELATE + ( + ct.location, + ( + SELECT SDO_GEOM.SDO_INTERSECTION(a.geom, b.geom, 0.5) + FROM sales_regions a, sales_regions b + WHERE a.id = 51 and b.id = 43 + ), + 'mask=anyinteract' + )='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-14.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-14.sql new file mode 100644 index 0000000..76d4ee3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-14.sql @@ -0,0 +1,9 @@ +-- Listing 9-14. SDO_UNION of Two Geometries +SELECT count(*) + FROM + ( + SELECT SDO_GEOM.SDO_UNION (a.geom, b.geom, 0.5) geom + FROM sales_regions b, sales_regions a + WHERE a.id=51 and b.id=43 + ) b, customers a + WHERE SDO_RELATE(a.location, b.geom, 'mask=anyinteract')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-15.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-15.sql new file mode 100644 index 0000000..79ce67b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-15.sql @@ -0,0 +1,12 @@ +-- Listing 9-15. Coverage of the Sales Regions: Performing a Union of All the Sales Regions +CREATE TABLE sales_region_coverage (coverage SDO_GEOMETRY); +DECLARE + coverage SDO_GEOMETRY := NULL; +BEGIN + FOR g IN (SELECT geom FROM sales_regions) LOOP + coverage := SDO_GEOM.SDO_UNION(coverage, g.geom, 0.5); + END LOOP; + INSERT INTO sales_region_coverage values (coverage); + COMMIT; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-16.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-16.sql new file mode 100644 index 0000000..da00f10 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-16.sql @@ -0,0 +1,6 @@ +-- Listing 9-16. SDO_DIFFERENCE of Competitor Region 2 with Sales Region 6 +CREATE TABLE exclusive_region_for_comp_2 AS + SELECT SDO_GEOM.SDO_DIFFERENCE(b.geom, a.geom, 0.5) geom + FROM sales_regions a, competitors_sales_regions b + WHERE b.id=2 + AND a.id=6 ; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-17.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-17.sql new file mode 100644 index 0000000..57eda96 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-17.sql @@ -0,0 +1,5 @@ +-- Listing 9-17. Identifying Customers in an Exclusive Zone of a Competitor +SELECT ct.id, ct.name + FROM exclusive_region_for_comp_2 excl, customers ct + WHERE SDO_RELATE(ct.location, excl.geom, 'mask=anyinteract')='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-18.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-18.sql new file mode 100644 index 0000000..f44819f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-18.sql @@ -0,0 +1,12 @@ +-- Listing 9-18. Combining Listings 9-16 and 9-17 +SELECT ct.id, ct.name + FROM sales_regions sr, competitors_sales_regions csr, customers ct + WHERE csr.id=2 + AND sr.id=6 + AND SDO_RELATE + ( + ct.location, + SDO_GEOM.SDO_DIFFERENCE(csr.geom, sr.geom, 0.5), + 'mask=anyinteract' + )='TRUE' + ORDER BY ct.id; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-19.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-19.sql new file mode 100644 index 0000000..e978243 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-19.sql @@ -0,0 +1,9 @@ +-- Listing 9-19. SDO_XOR of Sales Regions 43 and 51 to Identify Customers That Are Not Shared Between Them +SELECT count(*) + FROM ( + SELECT SDO_GEOM.SDO_XOR (a.geom, b.geom, 0.5) geom + FROM sales_regions b, sales_regions a + WHERE a.id=51 and b.id=43 + ) b, + customers a + WHERE SDO_RELATE(a.location, b.geom, 'mask=anyinteract')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-20.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-20.sql new file mode 100644 index 0000000..9e9a9e7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-20.sql @@ -0,0 +1,6 @@ +-- Listing 9-20. Area of the Intersection Region of Sales Region 43 and Sales Region 51 +SELECT SDO_GEOM.SDO_AREA + (SDO_GEOM.SDO_INTERSECTION(a.geom, b.geom, 0.5), 0.5, ' unit=sq_yard ' ) area + FROM sales_regions b, sales_regions a + WHERE a.id=51 + AND b.id=43; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-21.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-21.sql new file mode 100644 index 0000000..7be2a7c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-21.sql @@ -0,0 +1,4 @@ +-- Listing 9-21. Identifying Interstates Shorter Than 1 Mile +SELECT interstate + FROM us_interstates + WHERE SDO_GEOM.SDO_LENGTH(geom, 0.5, 'unit=mile') < 1; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-22.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-22.sql new file mode 100644 index 0000000..bcb263f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-22.sql @@ -0,0 +1,4 @@ +-- Listing 9-22. Computing the MBR of a Geometry +SELECT SDO_GEOM.SDO_MBR(a.geom) mbr + FROM sales_regions a + WHERE a.id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-23.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-23.sql new file mode 100644 index 0000000..76ce65f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-23.sql @@ -0,0 +1,5 @@ +-- Listing 9-23. Obtaining the MIN_ORDINATEs and MAX_ORDINATEs in a Specific Dimension +SELECT SDO_GEOM.SDO_MIN_MBR_ORDINATE(a.geom, 1) min_extent, + SDO_GEOM.SDO_MAX_MBR_ORDINATE(a.geom, 1) max_extent + FROM sales_regions a + WHERE a.id=1; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-24.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-24.sql new file mode 100644 index 0000000..d62195c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-24.sql @@ -0,0 +1,4 @@ +-- Listing 9-24. Computing the Convex Hull for the State of New Hampshire +SELECT SDO_GEOM.SDO_CONVEXHULL(a.geom, 0.5) cvxhl + FROM us_states a + WHERE a.state_abrv='NH'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-25.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-25.sql new file mode 100644 index 0000000..d134950 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-25.sql @@ -0,0 +1,4 @@ +-- Listing 9-25. Computing the Centroid for the State of New Hampshire +SELECT SDO_GEOM.SDO_CENTROID(a.geom, 0.5) ctrd + FROM us_states a + WHERE state_abrv='NH'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-26.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-26.sql new file mode 100644 index 0000000..f7e8110 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-26.sql @@ -0,0 +1,4 @@ +-- Listing 9-26. Obtaining a Point on the Surface of the Geometry of the State of Massachusetts +SELECT SDO_GEOM.SDO_POINTONSURFACE(a.geom, 0.5) pt + FROM us_states a + WHERE state_abrv='MA'; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-27.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-27.sql new file mode 100644 index 0000000..a74024d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-27.sql @@ -0,0 +1,3 @@ +-- Listing 9-27. Finding the Extent of a Set of Geometries Using SDO_AGGR_MBR +SELECT SDO_AGGR_MBR(a.location) extent + FROM branches a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-28.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-28.sql new file mode 100644 index 0000000..c9bd897 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-28.sql @@ -0,0 +1,3 @@ +-- Listing 9-28. Finding the Coverage of Branches Using SDO_AGGR_UNION +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(a.location, 0.5)) coverage + FROM branches a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-29.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-29.sql new file mode 100644 index 0000000..675bb16 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-29.sql @@ -0,0 +1,4 @@ +-- Listing 9-29. Union of Three Sales Regions (ids 43, 51, and 2) +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(a.geom, 0.5)) union_geom + FROM sales_regions a + WHERE id in (51, 43, 2) ; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-30.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-30.sql new file mode 100644 index 0000000..87b0e0b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-30.sql @@ -0,0 +1,3 @@ +-- Listing 9-30. Union of All Sales Regions to Obtain Business Coverage +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(a.geom, 0.5)) coverage + FROM sales_regions a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-31.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-31.sql new file mode 100644 index 0000000..99a563d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-31.sql @@ -0,0 +1,3 @@ +-- Listing 9-31. Finding the Coverage of sales_regions Using SDO_AGGR_CONVEXHULL + SELECT SDO_AGGR_CONVEXHULL(SDOAGGRTYPE(a.geom, 0.5)) coverage + FROM sales_regions a; diff --git a/ProOracleSpatialCode/Code/Chapter-09/listing-09-32.sql b/ProOracleSpatialCode/Code/Chapter-09/listing-09-32.sql new file mode 100644 index 0000000..23c86ed --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-09/listing-09-32.sql @@ -0,0 +1,4 @@ +-- Listing 9-32. Finding the Centroid of Customer Locations Using SDO_AGGR_CENTROID +SELECT SDO_AGGR_CENTROID(SDOAGGRTYPE(a.location, 0.5)) ctrd + FROM customers a + WHERE id<1000; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-01.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-01.sql new file mode 100644 index 0000000..dd287fc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-01.sql @@ -0,0 +1,10 @@ +-- Listing 10-1. Creating a Spatial Network Using Default Table Names +BEGIN + SDO_NET.CREATE_SDO_NETWORK ( + NETWORK => 'US_ROADS', + NO_OF_HIERARCHY_LEVELS => 1, + IS_DIRECTED => TRUE, + NODE_WITH_COST => FALSE + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-02.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-02.sql new file mode 100644 index 0000000..63449b9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-02.sql @@ -0,0 +1,5 @@ +-- Listing 10-2. Structure of Default Network Tables +describe US_ROADS_NODE$ +describe US_ROADS_LINK$ +describe US_ROADS_PATH$ +describe US_ROADS_PLINK$ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-03.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-03.sql new file mode 100644 index 0000000..1058ce4 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-03.sql @@ -0,0 +1,18 @@ +-- Listing 10-3. Network Creation with Explicit Table and Column Names +BEGIN + SDO_NET.CREATE_SDO_NETWORK ( + NETWORK => 'US_ROADS', + NO_OF_HIERARCHY_LEVELS => 1, + IS_DIRECTED => TRUE, + NODE_TABLE_NAME => 'US_INTERSECTIONS', + NODE_GEOM_COLUMN => 'LOCATION', + NODE_COST_COLUMN => NULL, + LINK_TABLE_NAME => 'US_STREETS', + LINK_GEOM_COLUMN => 'STREET_GEOM', + LINK_COST_COLUMN => 'STREET_LENGTH', + PATH_TABLE_NAME => 'US_PATHS', + PATH_GEOM_COLUMN => 'PATH_GEOM', + PATH_LINK_TABLE_NAME => 'US_PATH_LINKS' + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-04.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-04.sql new file mode 100644 index 0000000..efbceb3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-04.sql @@ -0,0 +1,39 @@ +-- Listing 10-4. Manual Network Creation + +-- Create the node table +CREATE TABLE us_intersections ( + node_id NUMBER, + location SDO_GEOMETRY, + CONSTRAINT us_intersections_pk PRIMARY KEY (node_id) +); + +-- Create the link table +CREATE TABLE us_streets ( + link_id NUMBER, + start_node_id NUMBER NOT NULL, + end_node_id NUMBER NOT NULL, + active CHAR(1), + street_geom SDO_GEOMETRY, + street_length NUMBER, + travel_time NUMBER, + CONSTRAINT us_streets_pk PRIMARY KEY (link_id) +); + +-- Create path table +CREATE TABLE us_paths ( + path_id NUMBER, + start_node_id NUMBER NOT NULL, + end_node_id NUMBER NOT NULL, + cost NUMBER, + simple VARCHAR2(1), + path_geom SDO_GEOMETRY, + CONSTRAINT us_paths_pk PRIMARY KEY (path_id) +); + +-- Create path link table +CREATE TABLE us_path_links ( + path_id NUMBER, + link_id NUMBER, + seq_no NUMBER, + CONSTRAINT us_path_links_pk PRIMARY KEY (path_id, link_id) +); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-05.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-05.sql new file mode 100644 index 0000000..f5abb6b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-05.sql @@ -0,0 +1,36 @@ +-- Listing 10-5. Setting Up Network Metadata +INSERT INTO USER_SDO_NETWORK_METADATA ( + NETWORK, + NETWORK_CATEGORY, + GEOMETRY_TYPE, + NO_OF_HIERARCHY_LEVELS, + NO_OF_PARTITIONS, + LINK_DIRECTION, + NODE_TABLE_NAME, + NODE_GEOM_COLUMN, + NODE_COST_COLUMN, + LINK_TABLE_NAME, + LINK_GEOM_COLUMN, + LINK_COST_COLUMN, + PATH_TABLE_NAME, + PATH_GEOM_COLUMN, + PATH_LINK_TABLE_NAME +) +VALUES ( + 'US_ROADS', -- network (primary key) + 'SPATIAL', -- network_category + 'SDO_GEOMETRY', -- geometry_type + 1, -- no_of_hierarchy_levels + 1, -- no_of_partitions + 'DIRECTED', -- link_direction + 'US_INTERSECTIONS', -- node_table_name + 'LOCATION', -- node_geom_column + NULL, -- node_cost_column (no cost at node level) + 'US_STREETS', -- link_table_name + 'STREET_GEOM', -- link_geom_column + 'STREET_LENGTH', -- link_cost_column + 'US_PATHS', -- path_table_name + 'PATH_GEOM', -- path_geom_column + 'US_PATH_LINKS' -- path_link_table_name +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-06.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-06.sql new file mode 100644 index 0000000..84c50f9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-06.sql @@ -0,0 +1,36 @@ +-- Listing 10-6. Setting Up Metadata for a Time-Based Road Network +INSERT INTO USER_SDO_NETWORK_METADATA ( + NETWORK, + NETWORK_CATEGORY, + GEOMETRY_TYPE, + NO_OF_HIERARCHY_LEVELS, + NO_OF_PARTITIONS, + LINK_DIRECTION, + NODE_TABLE_NAME, + NODE_GEOM_COLUMN, + NODE_COST_COLUMN, + LINK_TABLE_NAME, + LINK_GEOM_COLUMN, + LINK_COST_COLUMN, + PATH_TABLE_NAME, + PATH_GEOM_COLUMN, + PATH_LINK_TABLE_NAME +) +VALUES ( + 'US_ROADS_TIME', -- network (primary key) + 'SPATIAL', -- network_category + 'SDO_GEOMETRY', -- geometry_type + 1, -- no_of_hierarchy_levels + 1, -- no_of_partitions + 'DIRECTED', -- link_direction + 'US_INTERSECTIONS', -- node_table_name + 'LOCATION', -- node_geom_column + NULL, -- node_cost_column (no cost at node level) + 'US_STREETS', -- link_table_name + 'STREET_GEOM', -- link_geom_column + 'TRAVEL_TIME', -- link_cost_column + 'US_PATHS', -- path_table_name + 'PATH_GEOM', -- path_geom_column + 'US_PATH_LINKS' -- path_link_table_name +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-07.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-07.sql new file mode 100644 index 0000000..3ea2893 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-07.sql @@ -0,0 +1,16 @@ +-- Listing 10-7. Existing Water Network Tables +CREATE TABLE valves ( + valve_id NUMBER PRIMARY KEY, + valve_type VARCHAR2(20), + location SDO_GEOMETRY + -- ... other columns ... +); +CREATE TABLE pipes ( + pipe_id NUMBER PRIMARY KEY, + diameter NUMBER, + length NUMBER, + start_valve NUMBER NOT NULL REFERENCES valves, + end_valve NUMBER NOT NULL REFERENCES valves, + pipe_geom SDO_GEOMETRY + -- ... other columns ... +); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-08.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-08.sql new file mode 100644 index 0000000..8dc9ed3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-08.sql @@ -0,0 +1,15 @@ +-- Listing 10-8. Views over Existing Tables +CREATE VIEW net_valves (node_id, valve_type, location) AS + SELECT valve_id, + valve_type, + location + -- ...other columns ... + FROM valves; +CREATE VIEW net_pipes (link_id, start_node_id, end_node_id, length, pipe_geom) AS + SELECT pipe_id, + start_valve, + end_valve, + length, + pipe_geom + -- ... other columns ... + FROM pipes; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-09.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-09.sql new file mode 100644 index 0000000..8e4fa4c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-09.sql @@ -0,0 +1,16 @@ +-- Listing 10-9. Creating the Path and Path Link Tables +CREATE TABLE net_paths ( + path_id NUMBER, + start_node_id NUMBER NOT NULL, + end_node_id NUMBER NOT NULL, + cost NUMBER, + simple VARCHAR2(1), + path_geom SDO_GEOMETRY, + CONSTRAINT net_paths_pk PRIMARY KEY (path_id) +); +CREATE TABLE net_path_links ( + path_id NUMBER, + link_id NUMBER, + seq_no NUMBER, + CONSTRAINT net_path_links_pk PRIMARY KEY (path_id, link_id) +); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-10.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-10.sql new file mode 100644 index 0000000..c53af93 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-10.sql @@ -0,0 +1,36 @@ +-- Listing 10-10. Metadata for a Network on Existing Structures +INSERT INTO USER_SDO_NETWORK_METADATA ( + NETWORK, + NETWORK_CATEGORY, + GEOMETRY_TYPE, + NO_OF_HIERARCHY_LEVELS, + NO_OF_PARTITIONS, + LINK_DIRECTION, + NODE_TABLE_NAME, + NODE_GEOM_COLUMN, + NODE_COST_COLUMN, + LINK_TABLE_NAME, + LINK_GEOM_COLUMN, + LINK_COST_COLUMN, + PATH_TABLE_NAME, + PATH_GEOM_COLUMN, + PATH_LINK_TABLE_NAME +) +VALUES ( + 'WATER_NET', -- network (primary key) + 'SPATIAL', -- network_category + 'SDO_GEOMETRY', -- geometry_type + 1, -- no_of_hierarchy_levels + 1, -- no_of_partitions + 'UNDIRECTED', -- link_direction + 'NET_VALVES', -- node_table_name + 'LOCATION', -- node_geom_column + NULL, -- node_cost_column (no cost at node level) + 'NET_PIPES', -- link_table_name + 'PIPE_GEOM', -- link_geom_column + 'LENGTH', -- link_cost_column + 'NET_PATHS', -- path_table_name + 'PATH_GEOM', -- path_geom_column + 'NET_PATH_LINKS' -- path_link_table_name +); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-11.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-11.sql new file mode 100644 index 0000000..34d9daa --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-11.sql @@ -0,0 +1,2 @@ +-- Listing 10-11. Validating a Network Definition +select sdo_net.validate_network('us_roads') from dual; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-12.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-12.sql new file mode 100644 index 0000000..3766c6f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-12.sql @@ -0,0 +1,2 @@ +-- Listing 10-12. Dropping a Network +EXEC SDO_NET.DROP_NETWORK ('US_ROADS'); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-13.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-13.sql new file mode 100644 index 0000000..6ef8750 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-13.sql @@ -0,0 +1,13 @@ +-- Listing 10-13. Adding Spatial Metadata to Network Tables +BEGIN + SDO_NET.INSERT_GEOM_METADATA ( + 'US_ROADS', + SDO_DIM_ARRAY ( + SDO_DIM_ELEMENT ('Long', -180, +180, 1), + SDO_DIM_ELEMENT ('Lat', -90, +90, 1) + ), + 8307 + ); +END; +/ +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-14.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-14.sql new file mode 100644 index 0000000..91673ed --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-14.sql @@ -0,0 +1,25 @@ +-- Listing 10-14. Convenient Procedure for Getting Network Details +CREATE OR REPLACE PROCEDURE SHOW_NET_DETAILS (NETWORK_NAME VARCHAR2) AS +BEGIN + DBMS_OUTPUT.PUT_LINE ('Details on Network ' || NETWORK_NAME); + DBMS_OUTPUT.PUT_LINE ('NETWORK_EXISTS() = ' || SDO_NET.NETWORK_EXISTS(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('IS_HIERARCHICAL() = ' || SDO_NET.IS_HIERARCHICAL(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('IS_LOGICAL() = ' || SDO_NET.IS_LOGICAL(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('IS_SPATIAL() = ' || SDO_NET.IS_SPATIAL(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NETWORK_CATEGORY() = ' || SDO_NET.GET_NETWORK_CATEGORY(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('SDO_GEOMETRY_NETWORK() = ' || SDO_NET.SDO_GEOMETRY_NETWORK(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NETWORK_TYPE() = ' || SDO_NET.GET_NETWORK_TYPE(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_GEOMETRY_TYPE() = ' || SDO_NET.GET_GEOMETRY_TYPE(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NO_OF_HIERARCHY_LEVELS() = ' || SDO_NET.GET_NO_OF_HIERARCHY_LEVELS(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_LINK_DIRECTION() = ' || SDO_NET.GET_LINK_DIRECTION(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NODE_TABLE_NAME() = ' || SDO_NET.GET_NODE_TABLE_NAME(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NODE_COST_COLUMN() = ' || SDO_NET.GET_NODE_COST_COLUMN(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_NODE_GEOM_COLUMN() = ' || SDO_NET.GET_NODE_GEOM_COLUMN(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_LINK_TABLE_NAME() = ' || SDO_NET.GET_LINK_TABLE_NAME(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_LINK_COST_COLUMN() = ' || SDO_NET.GET_LINK_COST_COLUMN(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_LINK_GEOM_COLUMN() = ' || SDO_NET.GET_LINK_GEOM_COLUMN(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_PATH_TABLE_NAME() = ' || SDO_NET.GET_PATH_TABLE_NAME(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_PATH_GEOM_COLUMN() = ' || SDO_NET.GET_PATH_GEOM_COLUMN(NETWORK_NAME)); + DBMS_OUTPUT.PUT_LINE ('GET_PATH_LINK_TABLE_NAME() = ' || SDO_NET.GET_PATH_LINK_TABLE_NAME(NETWORK_NAME)); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-15.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-15.sql new file mode 100644 index 0000000..850c71e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-15.sql @@ -0,0 +1,3 @@ +-- Listing 10-15. Getting Network Details +SET SERVEROUTPUT ON +EXEC show_net_details ('US_ROADS'); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-16.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-16.sql new file mode 100644 index 0000000..87e8c4d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-16.sql @@ -0,0 +1,18 @@ +-- Listing 10-16. Defining the UNET Network +BEGIN + SDO_NET.CREATE_SDO_NETWORK ( + NETWORK => 'UNET', + NO_OF_HIERARCHY_LEVELS => 1, + IS_DIRECTED => FALSE, + NODE_TABLE_NAME => 'UNET_NODES', + NODE_GEOM_COLUMN => 'GEOM', + NODE_COST_COLUMN => NULL, + LINK_TABLE_NAME => 'UNET_LINKS', + LINK_COST_COLUMN => 'COST', + LINK_GEOM_COLUMN => 'GEOM', + PATH_TABLE_NAME => 'UNET_PATHS', + PATH_GEOM_COLUMN => 'GEOM', + PATH_LINK_TABLE_NAME => 'UNET_PLINKS' + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-17.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-17.sql new file mode 100644 index 0000000..e64e825 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-17.sql @@ -0,0 +1,37 @@ +-- Listing 10-17. Loading the UNET Network +-- Populate the node table +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (1, 'N1', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (1,3,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (2, 'N2', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (2,3,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (3, 'N3', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,3,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (4, 'N4', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (2,2,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (5, 'N5', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (3,2,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (6, 'N6', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,2,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (7, 'N7', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (1,1,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (8, 'N8', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (3,1,NULL), null, null)); +INSERT INTO unet_nodes (node_id, node_name, geom) VALUES (9, 'N9', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,1,NULL), null, null)); +COMMIT; + +-- Populate the link table +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 1, 'L1', 1, 2, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (1,3, 2,3))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 2, 'L2', 2, 3, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (2,3, 4,3))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 3, 'L3', 3, 6, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,3, 4,2))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 4, 'L4', 6, 9, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,2, 4,1))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 5, 'L5', 9, 8, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,1, 3,1))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 6, 'L6', 8, 7, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,1, 1,1))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 7, 'L7', 7, 1, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (1,1, 1,3))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 8, 'L8', 7, 4, 1.5, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (1,1, 2,2))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 9, 'L9', 4, 5, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (2,2, 3,2))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (10, 'L10', 5, 6, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,2, 4,2))); +INSERT INTO unet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (11, 'L11', 5, 8, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,2, 3,1))); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-18.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-18.sql new file mode 100644 index 0000000..52540c6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-18.sql @@ -0,0 +1,18 @@ +-- Listing 10-18. Defining the DNET Network +BEGIN + SDO_NET.CREATE_SDO_NETWORK ( + NETWORK => 'DNET', + NO_OF_HIERARCHY_LEVELS => 1, + IS_DIRECTED => TRUE, + NODE_TABLE_NAME => 'DNET_NODES', + NODE_GEOM_COLUMN => 'GEOM', + NODE_COST_COLUMN => NULL, + LINK_TABLE_NAME => 'DNET_LINKS', + LINK_COST_COLUMN => 'COST', + LINK_GEOM_COLUMN => 'GEOM', + PATH_TABLE_NAME => 'DNET_PATHS', + PATH_GEOM_COLUMN => 'GEOM', + PATH_LINK_TABLE_NAME => 'DNET_PLINKS' + ); +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-19.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-19.sql new file mode 100644 index 0000000..fcb56b1 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-19.sql @@ -0,0 +1,46 @@ +-- Listing 10-19. Loading the DNET Network +-- Populate the node table +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (1, 'N1', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (1,3,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (2, 'N2', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (2,3,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (3, 'N3', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,3,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (4, 'N4', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (2,2,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (5, 'N5', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (3,2,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (6, 'N6', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,2,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (7, 'N7', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (1,1,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (8, 'N8', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (3,1,NULL), NULL, NULL)); +INSERT INTO dnet_nodes (node_id, node_name, geom) VALUES (9, 'N9', SDO_GEOMETRY (2001, NULL, SDO_POINT_TYPE (4,1,NULL), NULL, NULL)); +COMMIT; + +-- Populate the link table +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 1, 'L1', 2, 1, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (2,3, 1,3))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 2, 'L2', 3, 2, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,3, 2,3))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 3, 'L3', 3, 6, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,3, 4,2))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (-3, 'L3', 6, 3, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,2, 4,3))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 4, 'L4', 6, 9, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,2, 4,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (-4, 'L4', 9, 6, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,1, 4,2))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 5, 'L5', 9, 8, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (4,1, 3,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (-5, 'L5', 8, 9, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,1, 4,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 6, 'L6', 8, 7, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,1, 1,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (-6, 'L6', 7, 8, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (1,1, 3,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 7, 'L7', 1, 7, 2, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (1,3, 1,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 8, 'L8', 4, 7, 1.5, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (2,2, 1,1))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES ( 9, 'L9', 5, 4, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,2, 2,2))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (10, 'L10', 5, 6, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,2, 4,2))); +INSERT INTO dnet_links (link_id, link_name, start_node_id, end_node_id, cost, geom) + VALUES (11, 'L11', 8, 5, 1, SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDINATE_ARRAY (3,1, 3,2))); +COMMIT; + diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-20.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-20.java new file mode 100644 index 0000000..e44e4b7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-20.java @@ -0,0 +1,26 @@ +// Listing 10-20. Using the shortestPath()Method + +// Get shortest path from node N4 to N3 +Network testNet = uNet; +startNodeId = 4; +endNodeId = 3; +Path path = NetworkManager.shortestPath (testNet, startNodeID ,endNodeId); + +// Show path cost and number of links +System.out.println ("Path cost: " + path.getCost() ); +System.out.println ("Number of links: "+ path.getNoOfLinks()); +System.out.println ("Simple path? "+ path.isSimple()); + +// Show the links traversed +System.out.println ("Links traversed:"); +Link[] linkArray = path.getLinkArray(); +for (int i = 0; i < linkArray.length; i++) + System.out.println (" Link " + linkArray[i].getID() + "\t" + + linkArray[i].getName() +"\t" + linkArray[i].getCost()); + +// Show the nodes traversed +System.out.println (" Nodes traversed:"); +Node [] nodeArray = path.getNodeArray(); +for (int i = 0; i < nodeArray.length; i++) + System.out.println (" Node " + nodeArray[i].getID() + "\t" + + nodeArray[i].getName() +"\t" + nodeArray[i].getCost()); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-21.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-21.java new file mode 100644 index 0000000..3e19b52 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-21.java @@ -0,0 +1,18 @@ +// Listing 10-21. Using the nearestNeighbors()Method + +// Find the two nearest neighbors of node N4 +Network testNet = uNet; +startNodeId = 4; +numNeighbors = 2; +Path[] pathArray = +NetworkManager.nearestNeighbors (testNet, startNodeId, numNeighbors); + +// Display the resulting paths +System.out.println (" " + pathArray.length + " nearest neighbors of node " + + startNodeId + " in network " + testNet.getName()); +for (int i = 0; i < pathArray.length; i++) +{ + Path path = pathArray[i]; + System.out.println(" node " + path.getEndNode().getID() + + ", path cost " + path.getCost()); +} diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-22.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-22.java new file mode 100644 index 0000000..64867c9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-22.java @@ -0,0 +1,19 @@ +// Listing 10-22. Using the withinCost()Method + +// Find nodes that are less than 3 'cost units' from node N2 +Network testNet = uNet; +startNodeId = 2; +maxCost = 3; +Path[] pathArray = +NetworkManager.withinCost (testNet, startNodeId, maxCost); + +// Display the resulting paths +System.out.println (" " + pathArray.length + " nodes from node " + + startNodeId + " in network " + testNet.getName() + + " within a cost of " + maxCost + ": "); +for (int i = 0; i < pathArray.length; i++) +{ + Path path = pathArray[i]; + System.out.println(" node " + path.getEndNode().getID() + + ", path cost " + path.getCost()); +} diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-23.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-23.java new file mode 100644 index 0000000..2a81f99 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-23.java @@ -0,0 +1,31 @@ +// Listing 10-23. Using the tspPath()Method + +// Traveling Salesperson Problem: nodes N7, N2, N3, N5, then back to N7 +Network testNet = uNet; +int[] nodeIds = {2,3,5}; +boolean isClosed = true; +boolean useExactCost = true; +Path tspPath = NetworkManager.tspPath (testNet, nodeIds, isClosed, + useExactCost, null); + +// Display the resulting path +Link[] linkArray = tspPath.getLinkArray(); +System.out.println (" Path cost: " + tspPath.getCost() ); +System.out.println (" Number of links: "+ tspPath.getNoOfLinks()); +System.out.println (" Simple path? "+ tspPath.isSimple()); +for (int i = 0; i < linkArray.length; i++) + System.out.println (" Link " + linkArray[i].getID() + "\t" + + linkArray[i].getName() + + "\t(cost: " + linkArray[i].getCost() + ")" ); + +// Construct input node array +Node[] inputNodes = new Node[nodeIds.length]; +for (int i = 0; i < nodeIds.length; i++) + inputNodes[i] = network.getNode(nodeIds[i]); + +// Display the visitation order +Node[] outputNodes = NetworkManager.tspOrder(inputNodes, tspPath); +System.out.println (" Actual node visitation order : " ); +for (int i = 0; i < outputNodes.length; i++) + System.out.println (" Node " + outputNodes[i].getID() + "\t" + + outputNodes[i].getName()); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-24.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-24.java new file mode 100644 index 0000000..d4965ee --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-24.java @@ -0,0 +1,12 @@ +// Listing 10-24. Using the findReachableNodes()Method + +// Find nodes that can be reached from node N4 +Network testNet = uNet; +nodeId = 4; +Node[] nodeArray = NetworkManager.findReachableNodes (testNet, nodeId); + +// Display the results +System.out.println (" " + nodeArray.length + " nodes in network " + + testNet.getName() + " are reachable from node " + nodeId); +for (int i = 0; i < nodeArray.length; i++) + System.out.println(" node " + nodeArray[i].getID()); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-25.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-25.java new file mode 100644 index 0000000..3411f7c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-25.java @@ -0,0 +1,19 @@ +// Listing 10-25. Using the mcst()Method + +// Compute the Minimum Spanning Cost Tree +Network mcstNet = NetworkManager.mcst(uNet); + +// Inspect the resulting network +System.out.println (" Nodes: " + mcstNet.getNoOfNodes()); +System.out.println (" Links: " + mcstNet.getNoOfLinks()); + +// Display MCST network links +Link[] linkArray = mcstNet.getLinkArray(); +double treeCost = 0; +for (int i = 0; i < linkArray.length; i++) { + System.out.println (" Link " + linkArray[i].getID() + "\t" + + linkArray[i].getName()+ "\t" + + linkArray[i].getCost()); +treeCost = treeCost + linkArray[i].getCost(); +} +System.out.println (" Total cost: \t\t" + treeCost); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-26.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-26.java new file mode 100644 index 0000000..33c28cf --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-26.java @@ -0,0 +1,17 @@ +// Listing 10-26. Using the allPaths()Method + +// Get all paths between nodes 3 and 4 +maxDepth = 1000; +maxCost = 1000; +maxSolutions = 1000; +Path[] pathArray = +NetworkManager.allPaths(uNet, 3, 4, maxDepth, maxCost, maxSolutions);; + +// Display the solutions found +for (int i = 0; i < pathArray.length; i++) +{ + Path p = pathArray[i]; + int numLinks = p.getNoOfLinks(); + double cost = p.getCost(); + System.out.println (" path["+i+"] links:" + numLinks + ", path cost "+ cost); +} diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-27.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-27.java new file mode 100644 index 0000000..6eeb393 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-27.java @@ -0,0 +1,13 @@ +// Listing 10-27. Using the shortestPaths()Method + +// Get the shortest paths between node 4 and all other nodes +Path[] pathArray = NetworkManager.shortestPaths(uNet, 4); +for (int i = 0; i < pathArray.length; i++) +{ + Path p = pathArray[i]; + int endNodeId = p.getEndNode().getID(); + int numLinks = p.getNoOfLinks(); + double cost = p.getCost(); + System.out.println (" path["+i+"] to node " + endNodeId + ", links:" + + numLinks + ", path cost "+ cost); +} diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-28.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-28.java new file mode 100644 index 0000000..eb6bd09 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-28.java @@ -0,0 +1,28 @@ +// Listing 10-28. Using the SystemConstraint Class + +// Set up a system constraint with a list of nodes to avoid and a cost limit +int[] avoidNodes = {5}; // Nodes to avoid +myConstraint = new SystemConstraint (uNet, avoidNodes); +myConstraint.setMaxCost(10); + +// Get shortest path from node N4 to N3 considering the constraint +Path path = NetworkManager.shortestPath (uNet, 3, 4, myConstraint); + +// Show path cost and number of links +System.out.println ("Path cost: " + path.getCost() ); +System.out.println ("Number of links: "+ path.getNoOfLinks()); +System.out.println ("Simple path? "+ path.isSimple()); + +// Show the links traversed +System.out.println ("Links traversed:"); +Link[] linkArray = path.getLinkArray(); +for (int i = 0; i < linkArray.length; i++) + System.out.println (" Link " + linkArray[i].getID() + "\t" + + linkArray[i].getName() +"\t" + linkArray[i].getCost()); + +// Show the nodes traversed +System.out.println (" Nodes traversed:"); +Node [] nodeArray = path.getNodeArray(); +for (int i = 0; i < nodeArray.length; i++) + System.out.println (" Node " + nodeArray[i].getID() + "\t" + + nodeArray[i].getName() +"\t" + nodeArray[i].getCost()); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-29.sql b/ProOracleSpatialCode/Code/Chapter-10/listing-10-29.sql new file mode 100644 index 0000000..682a96e --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-29.sql @@ -0,0 +1,5 @@ +-- Listing 10-29. Setting Link Levels for the UNET Network +UPDATE unet_links SET link_leveL = 1 WHERE link_id IN (1, 2, 3, 5, 6, 7, 10); +UPDATE unet_links SET link_leveL = 2 WHERE link_id IN (4, 11); +UPDATE unet_links SET link_level = 3 WHERE link_id IN (8, 9); +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-30.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-30.java new file mode 100644 index 0000000..5a04721 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-30.java @@ -0,0 +1,36 @@ +// Listing 10-30. Network Constraint + +import java.util.*; +import oracle.spatial.network.*; + +/** +* The following network constraint assumes that +* 1. each link has a link level (stored as LINK_LEVEL in { 1,2,3 }) +* 2. for a given target level (in { 1,2,3 } ), the following must hold: +* target Level 1 can only travel on link Level 1 +* target Level 2 can travel on link Level 1 and 2 +* target Level 3 can travel on link Level 1, 2, and 3 +*/ + +public class LinkLevelConstraint implements NetworkConstraint { + int p_targetLevel = 0; // Default; no restriction + + public LinkLevelConstraint (int targetLevel) { + p_targetLevel = targetLevel; + } + + public boolean requiresPathLinks() { + return false ; + } + + public boolean isSatisfied (AnalysisInfo info) { + if ( p_targetLevel == 0 ) // no restriction + return true ; + Link link = info.getNextLink() ; // potential link candidate + int linkLevel = link.getLinkLevel(); // get link Level + if ( link != null && p_targetLevel >= linkLevel ) + return true; + else + return false; + } +} diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-31.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-31.java new file mode 100644 index 0000000..d508c41 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-31.java @@ -0,0 +1,33 @@ +// Listing 10-31. Using the Network Constraint + +// Set up network constraint +int targetLevel = 1; +LinkLevelConstraint netConstraint = new LinkLevelConstraint (targetLevel); + +// Get shortest path from node N7 to N5 +Network testNet = uNet; +startNodeId = 7; +endNodeId = 5; +Path path = NetworkManager.shortestPath (testNet, startNodeID ,endNodeId); + +// Show path cost and number of links +System.out.println ("Path cost: " + path.getCost() ); +System.out.println ("Number of links: "+ path.getNoOfLinks()); +System.out.println ("Simple path? "+ path.isSimple()); + +// Show the links traversed +System.out.println ("Links traversed:"); +Link[] linkArray = path.getLinkArray(); +for (int i = 0; i < linkArray.length; i++) + System.out.println (" Link " + linkArray[i].getID() + "\t" + + linkArray[i].getName() +"\t" + + linkArray[i].getLinkLevel() + "\t" + + linkArray[i].getCost() ); + +// Show the nodes traversed +System.out.println (" Nodes traversed:"); +Node [] nodeArray = path.getNodeArray(); +for (int i = 0; i < nodeArray.length; i++) + System.out.println (" Node " + nodeArray[i].getID() + "\t" + + nodeArray[i].getName() +"\t" + + nodeArray[i].getCost()); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-32.java b/ProOracleSpatialCode/Code/Chapter-10/listing-10-32.java new file mode 100644 index 0000000..e92024a --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-32.java @@ -0,0 +1,69 @@ +// Listing 10-32. Creating a Network Using the Java API + +// Create the network object +String networkName = "MY_NET"; +Network myNet = NetworkFactory.createLogicalNetwork( + networkName, // networkName + 1, // noOfHierarchyLevels + true, // isDirected + networkName+"_NODE", // nodeTableName + "COST", // nodeCostColumn + networkName+"_LINK", // linkTableName + "COST", // linkCostColumn + networkName+"_PATH", // pathTableName + networkName+"_PLINK" // pathLinkTableName +); + +// Create the nodes +Node n1 = NetworkFactory.createNode (1, "N1"); +Node n2 = NetworkFactory.createNode (2, "N2"); +Node n3 = NetworkFactory.createNode (3, "N3"); +Node n4 = NetworkFactory.createNode (4, "N4"); +Node n5 = NetworkFactory.createNode (5, "N5"); +Node n6 = NetworkFactory.createNode (6, "N6"); +Node n7 = NetworkFactory.createNode (7, "N7"); +Node n8 = NetworkFactory.createNode (8, "N8"); +Node n9 = NetworkFactory.createNode (9, "N9"); + +// Create the links +Link l1 = NetworkFactory.createLink ( 1, "L1", n1, n2, 1); +Link l2 = NetworkFactory.createLink ( 2, "L2", n2, n3, 2); +Link l3 = NetworkFactory.createLink ( 3, "L3", n3, n6, 1); +Link l4 = NetworkFactory.createLink ( 4, "L4", n6, n9, 1); +Link l5 = NetworkFactory.createLink ( 5, "L5", n9, n8, 1); +Link l6 = NetworkFactory.createLink ( 6, "L6", n8, n7, 2); +Link l7 = NetworkFactory.createLink ( 7, "L7", n7, n1, 2); +Link l8 = NetworkFactory.createLink ( 8, "L8", n7, n4, 1.5); +Link l9 = NetworkFactory.createLink ( 9, "L9", n4, n5, 1); +Link l10 = NetworkFactory.createLink (10, "L10", n5, n6, 1); +Link l11 = NetworkFactory.createLink (11, "L11", n5, n8, 1); + +// Add the nodes to the network +myNet.addNode (n1); +myNet.addNode (n2); +myNet.addNode (n3); +myNet.addNode (n4); +myNet.addNode (n5); +myNet.addNode (n6); +myNet.addNode (n7); +myNet.addNode (n8); +myNet.addNode (n9); + +// Add the links to the network +myNet.addLink (l1); +myNet.addLink (l2); +myNet.addLink (l3); +myNet.addLink (l4); +myNet.addLink (l5); +myNet.addLink (l6); +myNet.addLink (l7); +myNet.addLink (l8); +myNet.addLink (l9); +myNet.addLink (l10); +myNet.addLink (l11); + +// Create the network tables in the database +NetworkFactory.createNetworkTables (dbConnection, myNet); + +// Write the network (this also writes the metadata) +NetworkManager.writeNetwork (dbConnection, myNet); diff --git a/ProOracleSpatialCode/Code/Chapter-10/listing-10-33.bat b/ProOracleSpatialCode/Code/Chapter-10/listing-10-33.bat new file mode 100644 index 0000000..b342994 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-10/listing-10-33.bat @@ -0,0 +1,4 @@ +REM Listing 10-33. Starting the Network Editor +set JAVA_ORACLE_HOME=D:\Oracle\Ora101 +set JAR_LIBS=%JAVA_ORACLE_HOME%/md/lib/sdondme.jar;%JAVA_ORACLE_HOME%/lib/xmlparserv2.jar;%JAVA_ORACLE_HOME%/jdbc/lib/classes12.jar;%JAVA_ORACLE_HOME%\md/lib/sdonm.jar;%JAVA_ORACLE_HOME%/md/lib/sdoapi.jar;%JAVA_ORACLE_HOME%/md/lib/sdoutl.jar +java -Xms512M -Xmx512M -cp %JAR_LIBS% oracle.spatial.network.editor.NetworkEditor diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-01.sql b/ProOracleSpatialCode/Code/Chapter-11/listing-11-01.sql new file mode 100644 index 0000000..be2fddf --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-01.sql @@ -0,0 +1,7 @@ +-- Listing 11-1. Branches in San Francisco +SELECT street_number num, + street_name, + city, + postal_code + FROM branches + WHERE city = 'SAN FRANCISCO'; diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-02.sql b/ProOracleSpatialCode/Code/Chapter-11/listing-11-02.sql new file mode 100644 index 0000000..9e75e8b --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-02.sql @@ -0,0 +1,9 @@ +-- Listing 11-2. Loading Maps, Themes, and Style Definitions +-- imp spatial/spatial file=styles.dmp full=y +INSERT INTO USER_SDO_STYLES + SELECT * FROM MY_STYLES; +INSERT INTO USER_SDO_THEMES + SELECT * FROM MY_THEMES; +INSERT INTO USER_SDO_MAPS + SELECT * FROM MY_MAPS; +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-03.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-03.xml new file mode 100644 index 0000000..f191c32 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-03.xml @@ -0,0 +1,11 @@ + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-04.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-04.xml new file mode 100644 index 0000000..3649550 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-04.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-05.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-05.xml new file mode 100644 index 0000000..092e056 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-05.xml @@ -0,0 +1,7 @@ + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-06.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-06.xml new file mode 100644 index 0000000..1313516 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-06.xml @@ -0,0 +1,5 @@ + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-07.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-07.xml new file mode 100644 index 0000000..3f29699 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-07.xml @@ -0,0 +1,11 @@ + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-08.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-08.xml new file mode 100644 index 0000000..2ec8f21 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-08.xml @@ -0,0 +1,6 @@ + + diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-09.xml b/ProOracleSpatialCode/Code/Chapter-11/listing-11-09.xml new file mode 100644 index 0000000..baca2cc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-09.xml @@ -0,0 +1,12 @@ + + + + <note text="Oracle (C) copyright 2004" + font="Bookman Old Style Bold Italic" + position="SOUTH_EAST"/> + <logo image_path="../../../web/myicons/orcl_logo_test.gif" + position="SOUTH_WEST"/> + <rendering + allow_local_adjustment="false" + use_globular_projection="false" /> +</global_map_config> diff --git a/ProOracleSpatialCode/Code/Chapter-11/listing-11-10.bat b/ProOracleSpatialCode/Code/Chapter-11/listing-11-10.bat new file mode 100644 index 0000000..1620fae --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-11/listing-11-10.bat @@ -0,0 +1,2 @@ +REM Listing 11-10 Starting the Map definition tool +java -cp $ORACLE_HOME/jdbc/lib/classes12.jar;mapdef.jar oracle.eLocation.console.GeneralManager diff --git a/ProOracleSpatialCode/Code/Chapter-11/web-examples.zip b/ProOracleSpatialCode/Code/Chapter-11/web-examples.zip new file mode 100644 index 0000000..e0900e9 Binary files /dev/null and b/ProOracleSpatialCode/Code/Chapter-11/web-examples.zip differ diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-01.sql b/ProOracleSpatialCode/Code/Chapter-12/listing-12-01.sql new file mode 100644 index 0000000..5582da5 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-01.sql @@ -0,0 +1,8 @@ +-- Listing 12-1. Loading the Geographical Data +$imp spatial/spatial file=map_large.dmp full=y +$imp spatial/spatial file=map_detailed.dmp full=y +$imp spatial/spatial file=net.dmp full=y +$imp spatial/spatial file=gc.dmp full=y +INSERT INTO USER_SDO_NETWORK_METADATA + SELECT * FROM my_network_metadata; +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-02.sql b/ProOracleSpatialCode/Code/Chapter-12/listing-12-02.sql new file mode 100644 index 0000000..ee2670f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-02.sql @@ -0,0 +1,26 @@ +-- Listing 12-2. Loading and Location-Enabling the Business Data +$imp spatial/spatial file=app_data.dmp full=y + +ALTER TABLE branches ADD (location SDO_GEOMETRY); +UPDATE branches + SET location = SDO_GCDR.GEOCODE_AS_GEOMETRY ( + 'SPATIAL', + SDO_KEYWORDARRAY ( + street_number || ' ' || street_name, + city || ' ' || postal_code), + 'US' + ); +COMMIT; + +INSERT INTO USER_SDO_GEOM_METADATA ( + TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) +VALUES ( + 'BRANCHES', + 'LOCATION', + SDO_DIM_ARRAY( + SDO_DIM_ELEMENT('Longitude', -180, 180, .5), + SDO_DIM_ELEMENT('Latitude', -90, 90, .5)), + 8307); + +CREATE INDEX branches_sx ON branches (location) + indextype is mdsys.spatial_index; diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-03.sql b/ProOracleSpatialCode/Code/Chapter-12/listing-12-03.sql new file mode 100644 index 0000000..dd2a0ef --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-03.sql @@ -0,0 +1,9 @@ +-- Listing 12-3. Loading Map Definitions +$imp spatial/spatial file=styles.dmp full=y +INSERT INTO USER_SDO_STYLES + SELECT * FROM my_styles; +INSERT INTO USER_SDO_THEMES + SELECT * FROM my_themes; +INSERT INTO USER_SDO_MAPS + SELECT * FROM my_maps; +COMMIT; diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-04.sql b/ProOracleSpatialCode/Code/Chapter-12/listing-12-04.sql new file mode 100644 index 0000000..45d10e0 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-04.sql @@ -0,0 +1,14 @@ +-- Listing 12-4. Functions to Extract x and y Coordinates +CREATE OR REPLACE FUNCTION get_point_x(g SDO_GEOMETRY) +RETURN NUMBER IS +BEGIN + RETURN g.SDO_POINT.X; +END; +/ + +CREATE OR REPLACE FUNCTION get_point_y(g SDO_GEOMETRY) +RETURN NUMBER IS +BEGIN + RETURN g.SDO_POINT.Y; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-05.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-05.java new file mode 100644 index 0000000..8e217f9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-05.java @@ -0,0 +1,53 @@ +// Listing 12-5. Reset Action + +// ----------------------------------------------------------------------- +// [Reset] button clicked +// Initialize the MapViewer object with the original center and size +// Load the network representation +// ----------------------------------------------------------------------- +if (userAction.equals("Reset")) { + + if (mv == null) + mapError = "Session lost - Resetting"; + + // Create and initialize new MapViewer object) + mv = new MapViewer(mapViewerURL); + mv.setDataSourceName(dataSource); // Data source + mv.setBaseMapName(baseMap); // Base map + for(int i=0; i<appThemes.length; i++) { // Additional themes + mv.addPredefinedTheme(appThemes[i]); // Theme name + mv.setThemeScale(appThemes[i], + appThemeMinScale, 0.0); // Scale limits + } + mv.setAllThemesEnabled(false); // Themes disabled + mv.setMapTitle(" "); // No title + mv.setImageFormat(MapViewer.FORMAT_PNG_URL); // Map format + mv.setDeviceSize(new Dimension(mapWidth, mapHeight)); // Map size + + // Save MapViewer object in session + session.setAttribute("MapviewerHandle", mv); + + // Get JDBC database connection + InitialContext ic = new InitialContext(); + DataSource ds = (DataSource) ic.lookup("jdbc/"+dataSource.toLowerCase()); + Connection conn = ds.getConnection(); + + // Load network + net = NetworkManager.readNetwork(conn, networkName); + + // Save Network object in session + session.setAttribute("NetworkHandle", net); + + // Release database connection + conn.close(); + + // Set initial map position and display it + mv.setCenterAndSize(initialCx, initialCy, initialSize); + mv.run(); + + // Set default options + clickAction = "reCenter"; + showRoute = false; + markX = 0; + markY = 0; +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-06.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-06.java new file mode 100644 index 0000000..792a522 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-06.java @@ -0,0 +1,10 @@ +// Listing 12-6. Zoom Actions + +// ----------------------------------------------------------------------- +// [Zoom XXX] button clicked +// Zoom in or out by a fixed factor +// ----------------------------------------------------------------------- +else if (userAction.equals("Zoom In")) + mv.zoomIn(zoomFactor); +else if (userAction.equals("Zoom Out")) + mv.zoomOut(zoomFactor); diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-07.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-07.java new file mode 100644 index 0000000..d44d650 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-07.java @@ -0,0 +1,14 @@ +// Listing 12-7. Pan Actions + +// ----------------------------------------------------------------------- +// [Pan XXX] button clicked +// Shift map 50% in the desired direction. +// ----------------------------------------------------------------------- +else if (userAction.equals("Pan W")) + mv.pan (0, mapHeight/2); +else if (userAction.equals("Pan N")) + mv.pan (mapWidth/2, 0); +else if (userAction.equals("Pan S")) + mv.pan (mapWidth/2, mapHeight); +else if (userAction.equals("Pan E")) + mv.pan (mapWidth, mapHeight/2); diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-08.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-08.java new file mode 100644 index 0000000..404ead2 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-08.java @@ -0,0 +1,13 @@ +// Listing 12-8. reCenter Action + +// ----------------------------------------------------------------------- +// Map clicked to recenter +// Use the coordinates of the clicked point as new map center +// ----------------------------------------------------------------------- +else if (userAction.equals("reCenter")) { + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + // Pan to that position + mv.pan (imgCX, imgCY); +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-09.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-09.java new file mode 100644 index 0000000..b676ca6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-09.java @@ -0,0 +1,13 @@ +// Listing 12-9. updateMap Action + +// ----------------------------------------------------------------------- +// [Update Map] button clicked +// Enable the themes selected by the user and refresh the map +// ----------------------------------------------------------------------- +else if (userAction.equals("Update Map")) { + if (checkedThemes == null) + mv.setAllThemesEnabled(false); + else + mv.enableThemes(checkedThemes); + mv.run(); +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-10.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-10.java new file mode 100644 index 0000000..906c2ff --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-10.java @@ -0,0 +1,80 @@ +// Listing 12-10. Find Action + +// ----------------------------------------------------------------------- +// [Find] button clicked: +// Geocode the entered address. +// Center map on the resulting coordinates. +// Set mark on that point. +// ----------------------------------------------------------------------- +else if (userAction.equals("Find")) { + + // Extract address details + String[] addressLines = findAddress.split("\r\n"); + + // Construct query to geocoder + String gcQuery = + "SELECT "+ + "G.GEO_ADDR.MATCHCODE, G.GEO_ADDR.LONGITUDE, G.GEO_ADDR.LATITUDE, " + + "G.GEO_ADDR.HOUSENUMBER || ' ' || G.GEO_ADDR.STREETNAME, " + + "G.GEO_ADDR.SETTLEMENT || ' ' || G.GEO_ADDR.POSTALCODE " + + "FROM (SELECT SDO_GCDR.GEOCODE(USER ,SDO_KEYWORDARRAY("; + for (int i=0; i<addressLines.length; i++) { + gcQuery = gcQuery + "'" + addressLines[i] + "'"; + if (i < addressLines.length-1) + gcQuery = gcQuery + ","; + } + gcQuery = gcQuery + "), 'US', 'DEFAULT') " + + "GEO_ADDR FROM DUAL) G"; + + // Send query + String[][] f = mv.doQuery(dataSource, gcQuery); + + // Extract match code. Proceed only if > 0 + int matchCode = Integer.parseInt(f[1][0]); + if (matchCode > 0) { + + // Extract X and Y coordinates from geocode result + double destX = Double.valueOf(f[1][1]).doubleValue(); + double destY = Double.valueOf(f[1][2]).doubleValue(); + + // Extract full street address from result + String streetAddress = f[1][3]; + + // Transform result from row-major to column-major + geocodeInfo = new String[f[0].length-3]; + for (int i=0; i<f[0].length-3; i++) + geocodeInfo[i] = f [1][i+3]; + + // Center map on the new address and zoom in + mv.setCenterAndSize(destX, destY, markerMapSize); + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from that mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked and label it + // with the first address line + mv.addPointFeature ( + destX, destY, + mapSrid, + markerStyle, + streetAddress, + markerLabelStyle, + null, + true); + + // Save new mark + markX = destX; + markY = destY; + + // Show SQL statement + mapError = gcQuery; + + // Refresh map + mv.run(); + } + else + mapError = "Address not found"; +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-11.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-11.java new file mode 100644 index 0000000..0986759 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-11.java @@ -0,0 +1,66 @@ +// Listing 12-11. identify Action + +// ----------------------------------------------------------------------- +// Map clicked to identify a feature. +// Get the coordinates of the clicked point +// use them to query the feature from the selected theme +// ----------------------------------------------------------------------- +else if (userAction.equals("identify")) { + + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + + if (identifyTheme == null) + mapError = "No theme selected to identify"; + else if (!mv.getThemeEnabled(identifyTheme)) + mapError = "Theme "+identifyTheme+" is not visible"; + else { + + // Locate the feature and get details + // Notes: + // 1. The identify() method needs a TABLE NAME, not a theme name. + // We just assume that the theme and table name are the same. + // 2. We query a rectangle of 4 pixels around the user click. Notice, + // however, that pixels have their origin at the UPPER-LEFT corner + // of the image, whereas ground coordinates use the LOWER-LEFT + // corner. + String[][] f = mv.identify(dataSource, identifyTheme, colsToSelect, + geoColumn, mapSrid, + imgCX-4, imgCY+4, + imgCX+4, imgCY-4, + false); + + // The result is one row per matching record, but we want to display + // results as one column per record. + if (f!= null && f.length > 0) { + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + } else + mapError = "No matching " + identifyTheme + " found"; + + if (featuresFound > 0) { + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from previous mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked + Point2D p = mv.getUserPoint(imgCX,imgCY); + mv.addPointFeature (p.getX(), p.getY(), + mapSrid, markerStyle, null, null, null); + + // Save new mark + markX = p.getX(); + markY = p.getY(); + + // Refresh map + mv.run(); + } + } +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-12.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-12.java new file mode 100644 index 0000000..6fa23f9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-12.java @@ -0,0 +1,31 @@ +// Listing 12-12. setMark Action + +// ----------------------------------------------------------------------- +// Map clicked to set a mark +// Get the coordinates of the clicked point and use them to set a mark +// at that point +// ----------------------------------------------------------------------- +else if (userAction.equals("setMark")) { + + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from previous mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked + Point2D p = mv.getUserPoint(imgCX,imgCY); + mv.addPointFeature (p.getX(), p.getY(), + mapSrid, markerStyle, null, null, null); + + // Save new mark + markX = p.getX(); + markY = p.getY(); + + // Refresh map + mv.run(); +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-13.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-13.java new file mode 100644 index 0000000..00b1ec6 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-13.java @@ -0,0 +1,68 @@ +// Listing 12-13. distSearch Action + +// ----------------------------------------------------------------------- +// [distSearch] button clicked +// Search for all neighbors within distance D from the current set mark. +// ----------------------------------------------------------------------- +else if (userAction.equals("distSearch")) { + if (markX == 0 && markY == 0) + mapError = "No address or mark set"; + else if (!mv.getThemeEnabled(distSearchTheme)) + mapError = "Theme "+distSearchTheme+" is not visible"; + else if (distSearchParam <= 0) + mapError = "Enter search distance"; + else { + + // Construct point object from current location mark + JGeometry geom = new JGeometry(markX, markY, mapSrid); + + // Construct spatial query + String sqlQuery = "SELECT "+geoColumn+" FROM " + distSearchTheme + + " WHERE SDO_WITHIN_DISTANCE ("+ geoColumn + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'DISTANCE="+distSearchParam+" UNIT=M') = 'TRUE'"; + mapError = "Executing query: "+ sqlQuery; + + // Add a JDBC theme to highlight the results of the query + mv.addJDBCTheme ( + dataSource, // Data source + "SEARCH RESULTS", // Theme to search + sqlQuery, // SQL Query + geoColumn, // Name of spatial column + null, // srid + queryStyle, // renderStyle + null, // labelColumn + null, // labelStyle + true // passThrough + ); + + // Perform the query + String[][] f = mv.queryWithinRadius( + dataSource, // Data source + distSearchTheme, // Theme to search + colsToSelect, // Names of columns to select + null, // Extra condition + markX, markY, // Center point (current mark) + distSearchParam, // Distance to search + false // Center point is in ground coordinates + ); + + if (f!= null && f.length > 0) { + + // The result is one row per matching record, but we want to display + // results as one column per record. + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + + // Refresh map + mv.run(); + + } else + mapError = "No matching " + distSearchTheme + " found"; + + } +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-14.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-14.java new file mode 100644 index 0000000..cce2ccc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-14.java @@ -0,0 +1,70 @@ +// Listing 12-14. nnSearch Action + +// ----------------------------------------------------------------------- +// [nnSearch] button clicked +// Search the N nearest neighbors from the current set mark. +// ----------------------------------------------------------------------- +else if (userAction.equals("nnSearch")) { + if (markX == 0 && markY == 0) + mapError = "No address or mark set"; + else if (!mv.getThemeEnabled(nnSearchTheme)) + mapError = "Theme "+nnSearchTheme+" is not visible"; + else if (nnSearchParam <= 0) + mapError = "Enter number of matches to search"; + else { + + // Construct spatial query + String sqlQuery = "SELECT "+geoColumn+", SDO_NN_DISTANCE(1) DISTANCE" + + " FROM " + nnSearchTheme + + " WHERE SDO_NN ("+ geoColumn + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES="+nnSearchParam+"',1) = 'TRUE'" + + " ORDER BY DISTANCE"; + mapError = "Executing query: "+ sqlQuery; + + // Add a JDBC theme to highlight the results of the query + mv.addJDBCTheme ( + dataSource, // Data source + "SEARCH RESULTS", // Theme to search + sqlQuery, // SQL Query + geoColumn, // Name of spatial column + null, // srid + queryStyle, // renderStyle + null, // labelColumn + null, // labelStyle + true // passThrough + ); + + // Perform the query + String[][] f = mv.queryNN( + dataSource, // Data source + nnSearchTheme, // Theme to search + colsToSelect, // Names of columns to select + nnSearchParam, // Number of neighbors + markX, markY, // Center point (current mark) + null, // Extra condition + false, // Center point is in ground coordinates + null + ); + + if (f== null || f.length == 0) + mapError = "No matching " + nnSearchTheme + " found"; + else { + + // The result is one row per matching record, but we want to display + // results as one column per record. + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + + // Remove any existing route + mv.removeAllLinearFeatures(); + + // Refresh map + mv.run(); + } + } +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-15.java b/ProOracleSpatialCode/Code/Chapter-12/listing-12-15.java new file mode 100644 index 0000000..0e8e4d3 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-15.java @@ -0,0 +1,49 @@ +// Listing 12-15. Calculating a Route + +if (showRoute) { + + // Extract coordinates of destination node + double destX = Double.valueOf(f[1][numVisibleCols]).doubleValue(); + double destY = Double.valueOf(f[1][numVisibleCols+1]).doubleValue(); + + // Snap destination to nearest network node + String qd = "SELECT NODE_ID FROM " + net.getNodeTableName() + + " WHERE SDO_NN ("+net.getNodeGeomColumn() + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + destX + "," + destY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES=1') = 'TRUE'"; + String [][] sd = mv.doQuery(dataSource, qd); + int destNodeId = Integer.parseInt(sd[1][0]); + + // Snap start (mark) to nearest network node + String qs = "SELECT NODE_ID FROM " + net.getNodeTableName() + + " WHERE SDO_NN ("+net.getNodeGeomColumn() + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES=1') = 'TRUE'"; + String [][] ss = mv.doQuery(dataSource, qs); + int startNodeId = Integer.parseInt(ss[1][0]); + + // Get path from mark to destination node + Path p = NetworkManager.shortestPath(net, startNodeId, destNodeId); + + // Check that we got a valid path back + if (p != null && p.getNoOfLinks() > 0) { + + // Compute path geometry + p.computeGeometry(0.5); + JGeometry g = p.getGeometry(); + + // Add route geometry to map + mv.addLinearFeature ( + g.getOrdinatesArray(), // Ordinates + mapSrid, // SRID + "L.TRANSPARENT", // Line style + null, // Label column + null // Label style + ); + + } else + mapError = "Unable to compute route"; + +} diff --git a/ProOracleSpatialCode/Code/Chapter-12/listing-12-16.jsp b/ProOracleSpatialCode/Code/Chapter-12/listing-12-16.jsp new file mode 100644 index 0000000..88e61e7 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-12/listing-12-16.jsp @@ -0,0 +1,1108 @@ +<!-- Listing 12-16. Example Application --> +<!-- + +This is an application that illustrates how to integrate various +features of Oracle Spatial into a web-based application. + +It supports the following actions + +- display of a base map showing street-level information +- overlay the map with business data (customers, branches, and competitors) +- zoom, pan, and recenter the map +- select a customer, branch, or competitor and display details +- enter a street address and center the map on that address +- set location marks using mouse clicks +- find all customers (or branches or competitors) that are within a chosen distance + from a location mark or customer (or branch or competitor) +- find the N nearest customers (or branches or competitors) from a location mark + or customer (or branch or competitor) +- show the shortest route from the location mark to the nearest customer (or branch + or competitor). + +The application also shows the SQL queries it sends to the database to do the +"within distance" and "nearest neighbor" searches). + +The JSP can be called with parameters to define the initial +map to display: map name, data source, initial center, and size: + + dataSource + baseMap + initialCx + initialCy + initialSize + +In addition, the parameter "debug" adds a display of the XML +requests and responses. + +--> + +<%@ page contentType="text/html;charset=UTF-8"%> +<%@ page language="java" %> +<%@ page import="java.net.*" %> +<%@ page import="java.io.*" %> +<%@ page import="java.awt.geom.Point2D" %> +<%@ page import="java.awt.Dimension" %> +<%@ page import="javax.naming.*" %> +<%@ page import="javax.sql.*" %> +<%@ page import="java.sql.*" %> +<%@ page import="oracle.lbs.mapclient.MapViewer" %> +<%@ page import="oracle.spatial.geometry.*" %> +<%@ page import="oracle.spatial.network.*" %> + +<% + + // Constants + int mapWidth = 350; // Map width in pixels + int mapHeight = 300; // Map height in pixels + String defDataSource = "SPATIAL10G";// Default data source name + String defBaseMap = "US_CITY_MAP"; // Default map name + String defNetwork = "NET_SF"; // Default network name + double defCx = -122.43302833333328; // Default origin longitude + double defCy = 37.7878425; // Default origin latitude + double defMapSize = 0.01; // Initial map size + double zoomFactor = 1.5; // Zoom factor + int mapSrid = 8307; // Map coordinate system + String[] appThemes // Application themes + = new String [] { + "BRANCHES", + "COMPETITORS", + "CUSTOMERS" + }; + double appThemeMinScale = 0.005; // Scale at which app themes are displayed + String[] colsToSelect // Columns to select for application themes + = new String[]{ + "ID", + "NAME", + "STREET_NUMBER||' '||STREET_NAME ADDRESS", + "CITY", + "POSTAL_CODE", + "STATE", + "PHONE_NUMBER", + "GET_POINT_X(LOCATION) LONGITUDE", + "GET_POINT_Y(LOCATION) LATITUDE" + }; + int numVisibleCols = 7; // Number of columns to display for searches + String geoColumn = "LOCATION"; // Name of geometry column in app themes + double markerMapSize = 0.01; // Map size of map for address searches + String markerStyle ="M.YELLOW PIN"; // Style for location mark + String markerLabelStyle // Style for address label + = "T.ADDRESS_MARK_NAME"; + String queryStyle = "M.CYAN PIN"; // Style for query result markers + + // Name of this JSP + String jspURL = response.encodeURL(request.getRequestURI()); + + // URL of MapViewer servlet + String mapViewerURL = + "http://"+ request.getServerName()+":" + + request.getServerPort() + + request.getContextPath()+"/omserver"; + + // Static request parameters + String dataSource = null; // Data source name + String baseMap = null; // Map name + double initialCx = 0; // Initial Map center X in map coordinates + double initialCy = 0; // Initial Map center Y in map coordinates + double initialSize = 0; // Initial Map size in map coordinates + boolean debug = false; // Debug mode + String networkName = null; // Name of network for network-based searches + + // Current map and search parameters + double cx = 0; // Current map center X in map coordinates + double cy = 0; // Current map center Y in map coordinates + double mapSize = 0; // Current map size in map coordinates + + double mapScale = 0; // Scale of the current map + String[] checkedThemes; // List of checked themes + String identifyTheme; // Name of theme to identify + double markX = 0; // Mark X + double markY = 0; // Mark Y + String findAddress; // Street address to find + int nnSearchParam; // Number of matches for NN search + + String nnSearchTheme; // Theme to search for nearest neighbors + boolean showRoute; // Show route to nearest neighbor + double distSearchParam; // Distance for within-distance search + String distSearchTheme; // Theme to search for within-distance search + + // User action + String userAction = null; // User requested action + String clickAction = null; // Action to perform on mouse click + + // HTML output + String imgURL = ""; // URL of returned map + String mapRequest = ""; // Map request (XML) + String mapResponse = ""; // Map response (XML) + String mapError = ""; // Error or information message + int featuresFound = 0; // Number of features found + String[][] featureInfo = null; // Attributes of selected features + String[] geocodeInfo = null; // Result of geocode operation + + // Load static request parameters + dataSource = request.getParameter("dataSource"); + if (dataSource != null) + dataSource = dataSource.toUpperCase(); + else + dataSource = defDataSource; + baseMap = request.getParameter("baseMap"); + if (baseMap != null) + baseMap = baseMap.toUpperCase(); + else + baseMap = defBaseMap; + initialCx = request.getParameter("initialCx") != null ? + Double.valueOf(request.getParameter("initialCx")).doubleValue() : defCx; + initialCy = request.getParameter("initialCy") != null ? + Double.valueOf(request.getParameter("initialCy")).doubleValue() : defCy; + initialSize = request.getParameter("initialSize") != null ? + Double.valueOf(request.getParameter("initialSize")).doubleValue() : defMapSize; + debug = request.getParameter("debug") != null ? + Boolean.valueOf(request.getParameter("debug")).booleanValue(): false; + networkName = request.getParameter("networkName"); + if (networkName != null) + networkName = networkName.toUpperCase(); + else + networkName = defNetwork; + + // Load dynamic request parameters: + + // - Current location mark + markX = request.getParameter("markX") != null ? + Double.valueOf(request.getParameter("markX")).doubleValue() : 0; + markY = request.getParameter("markY") != null ? + Double.valueOf(request.getParameter("markY")).doubleValue() : 0; + + // - List of checked themes and theme to identify + checkedThemes = request.getParameterValues("checkedThemes"); + identifyTheme = request.getParameter("identifyTheme"); + + // - Address to find + findAddress = request.getParameter("findAddress"); + if (findAddress == null) + findAddress = ""; + + // - Nearest neighbor search parameters + nnSearchParam = request.getParameter("nnSearchParam") != null ? + Integer.parseInt(request.getParameter("nnSearchParam")) : 1; + nnSearchTheme = request.getParameter("nnSearchTheme"); + showRoute = request.getParameter("showRoute") != null ? + Boolean.valueOf(request.getParameter("showRoute")).booleanValue(): false; + + // - Within-distance search parameters + distSearchParam = request.getParameter("distSearchParam") != null ? + Double.valueOf(request.getParameter("distSearchParam")).doubleValue() : 0; + distSearchTheme = request.getParameter("distSearchTheme"); + + // Reload MapViewer from session (if present) + MapViewer mv = (MapViewer) session.getAttribute("MapviewerHandle"); + // Reload Network from session (if present) + Network net = (Network) session.getAttribute("NetworkHandle"); + + // Get user action. Default is "Reset" + userAction = request.getParameter("userAction"); + if (userAction == null || mv == null) + userAction = "Reset"; + clickAction = request.getParameter("clickAction"); + if (clickAction == null) + clickAction = "reCenter"; + if (request.getParameter("mapImage.x") != null) + userAction = clickAction; + if (request.getParameter("distSearch") != null) + userAction = "distSearch"; + if (request.getParameter("nnSearch") != null) + userAction = "nnSearch"; + if (request.getParameter("clearSearch") != null) + userAction = "Clear Search"; + mapError = userAction; + + // Dispatch and process user action + if (userAction != null) { + + // ----------------------------------------------------------------------- + // [Reset] button clicked + // Initialize the MapViewer object with the original center and size + // Load the network representation + // ----------------------------------------------------------------------- + if (userAction.equals("Reset")) { + + if (mv == null) + mapError = "Session lost - Resetting"; + + // Create and initialize new MapViewer object) + mv = new MapViewer(mapViewerURL); + mv.setDataSourceName(dataSource); // Data source + mv.setBaseMapName(baseMap); // Base map + for(int i=0; i<appThemes.length; i++) { // Additional themes + mv.addPredefinedTheme(appThemes[i]); // Theme name + mv.setThemeScale(appThemes[i], + appThemeMinScale, 0.0); // Scale limits + } + mv.setAllThemesEnabled(false); // Themes disabled + mv.setMapTitle(" "); // No title + mv.setImageFormat(MapViewer.FORMAT_PNG_URL); // Map format + mv.setDeviceSize(new Dimension(mapWidth, mapHeight)); // Map size + + // Save MapViewer object in session + session.setAttribute("MapviewerHandle", mv); + + // Get JDBC database connection + InitialContext ic = new InitialContext(); + DataSource ds = (DataSource) ic.lookup("jdbc/"+dataSource.toLowerCase()); + Connection conn = ds.getConnection(); + + // Load network + net = NetworkManager.readNetwork(conn, networkName); + + // Save Network object in session + session.setAttribute("NetworkHandle", net); + + // Release database connection + conn.close(); + + // Set initial map position and display it + mv.setCenterAndSize(initialCx, initialCy, initialSize); + mv.run(); + + // Set default options + clickAction = "reCenter"; + showRoute = false; + markX = 0; + markY = 0; + } + + // ----------------------------------------------------------------------- + // [Zoom XXX] button clicked + // Zoom in or out by a fixed factor + // ----------------------------------------------------------------------- + else if (userAction.equals("Zoom In")) + mv.zoomIn(zoomFactor); + else if (userAction.equals("Zoom Out")) + mv.zoomOut(zoomFactor); + + // ----------------------------------------------------------------------- + // [Pan XXX] button clicked + // Shift map 50% in the desired direction. + // ----------------------------------------------------------------------- + else if (userAction.equals("Pan W")) + mv.pan (0, mapHeight/2); + else if (userAction.equals("Pan N")) + mv.pan (mapWidth/2, 0); + else if (userAction.equals("Pan S")) + mv.pan (mapWidth/2, mapHeight); + else if (userAction.equals("Pan E")) + mv.pan (mapWidth, mapHeight/2); + + // ----------------------------------------------------------------------- + // Map clicked to recenter + // Use the coordinates of the clicked point as new map center + // ----------------------------------------------------------------------- + else if (userAction.equals("reCenter")) { + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + // Pan to that position + mv.pan (imgCX, imgCY); + } + + // ----------------------------------------------------------------------- + // [Update Map] button clicked + // Enable the themes selected by the user and refresh the map + // ----------------------------------------------------------------------- + else if (userAction.equals("Update Map")) { + if (checkedThemes == null) + mv.setAllThemesEnabled(false); + else + mv.enableThemes(checkedThemes); + mv.run(); + } + + // ----------------------------------------------------------------------- + // Map clicked to set a mark + // Get the coordinates of the clicked point and use them to set a mark + // at that point + // ----------------------------------------------------------------------- + else if (userAction.equals("setMark")) { + + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from previous mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked + Point2D p = mv.getUserPoint(imgCX,imgCY); + mv.addPointFeature (p.getX(), p.getY(), + mapSrid, markerStyle, null, null, null); + + // Save new mark + markX = p.getX(); + markY = p.getY(); + + // Refresh map + mv.run(); + } + + // ----------------------------------------------------------------------- + // Map clicked to identify a feature. + // Get the coordinates of the clicked point + // use them to query the feature from the selected theme + // ----------------------------------------------------------------------- + else if (userAction.equals("identify")) { + + // Extract coordinates of mouse click + int imgCX = Integer.parseInt(request.getParameter("mapImage.x")); + int imgCY = Integer.parseInt(request.getParameter("mapImage.y")); + + if (identifyTheme == null) + mapError = "No theme selected to identify"; + else if (!mv.getThemeEnabled(identifyTheme)) + mapError = "Theme "+identifyTheme+" is not visible"; + else { + + // Locate the feature and get details + // Notes: + // 1. The identify() method needs a TABLE NAME, not a theme name. + // We just assume that the theme and table name are the same. + // 2. We query a rectangle of 4 pixels around the user click. Notice, + // however, that pixels have their origin at the UPPER-LEFT corner + // of the image, whereas ground coordinates use the LOWER-LEFT + // corner. + String[][] f = mv.identify(dataSource, identifyTheme, colsToSelect, + geoColumn, mapSrid, + imgCX-4, imgCY+4, + imgCX+4, imgCY-4, + false); + + // The result is one row per matching record, but we want to display + // results as one column per record. + if (f!= null && f.length > 0) { + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + } else + mapError = "No matching " + identifyTheme + " found"; + + if (featuresFound > 0) { + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from previous mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked + Point2D p = mv.getUserPoint(imgCX,imgCY); + mv.addPointFeature (p.getX(), p.getY(), + mapSrid, markerStyle, null, null, null); + + // Save new mark + markX = p.getX(); + markY = p.getY(); + + // Refresh map + mv.run(); + } + } + } + + // ----------------------------------------------------------------------- + // [Clear] button clicked: + // Remove the mark and refresh map + // ----------------------------------------------------------------------- + else if (userAction.equals("Clear")) { + + if (markX != 0 || markY != 0) { + + // Clear current address + findAddress = ""; + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from that mark + mv.removeAllLinearFeatures(); + + // Reset mark + markX = 0; + markY = 0; + + // Refresh map + mv.run(); + + } + } + + // ----------------------------------------------------------------------- + // [Go to Mark] button clicked + // Center map on mark + // ----------------------------------------------------------------------- + else if (userAction.equals("Go To Mark")) { + if (markX == 0 && markY == 0) + mapError = "No address or mark set"; + else { + mv.setCenter(markX, markY); + mv.run(); + } + } + + // ----------------------------------------------------------------------- + // [Find] button clicked: + // Geocode the entered address. + // Center map on the resulting coordinates. + // Set mark on that point. + // ----------------------------------------------------------------------- + else if (userAction.equals("Find")) { + + // Extract address details + String[] addressLines = findAddress.split("\r\n"); + + // Construct query to geocoder + String gcQuery = + "SELECT "+ + "G.GEO_ADDR.MATCHCODE, G.GEO_ADDR.LONGITUDE, G.GEO_ADDR.LATITUDE, " + + "G.GEO_ADDR.HOUSENUMBER || ' ' || G.GEO_ADDR.STREETNAME, " + + "G.GEO_ADDR.SETTLEMENT || ' ' || G.GEO_ADDR.POSTALCODE " + + "FROM (SELECT SDO_GCDR.GEOCODE(USER ,SDO_KEYWORDARRAY("; + for (int i=0; i<addressLines.length; i++) { + gcQuery = gcQuery + "'" + addressLines[i] + "'"; + if (i < addressLines.length-1) + gcQuery = gcQuery + ","; + } + gcQuery = gcQuery + "), 'US', 'DEFAULT') " + + "GEO_ADDR FROM DUAL) G"; + + // Send query + String[][] f = mv.doQuery(dataSource, gcQuery); + + // Extract match code. Proceed only if > 0 + int matchCode = Integer.parseInt(f[1][0]); + if (matchCode > 0) { + + // Extract X and Y coordinates from geocode result + double destX = Double.valueOf(f[1][1]).doubleValue(); + double destY = Double.valueOf(f[1][2]).doubleValue(); + + // Extract full street address from result + String streetAddress = f[1][3]; + + // Transform result from row-major to column-major + geocodeInfo = new String[f[0].length-3]; + for (int i=0; i<f[0].length-3; i++) + geocodeInfo[i] = f [1][i+3]; + + // Center map on the new address and zoom in + mv.setCenterAndSize(destX, destY, markerMapSize); + + // Remove any existing marker + mv.removeAllPointFeatures(); + + // Remove any route from that mark + mv.removeAllLinearFeatures(); + + // Add a marker at the point clicked and label it + // with the first address line + mv.addPointFeature ( + destX, destY, + mapSrid, + markerStyle, + streetAddress, + markerLabelStyle, + null, + true); + + // Save new mark + markX = destX; + markY = destY; + + // Show SQL statement + mapError = gcQuery; + + // Refresh map + mv.run(); + } + else + mapError = "Address not found"; + } + + // ----------------------------------------------------------------------- + // [distSearch] button clicked + // Search for all neighbors within distance D from the current set mark. + // ----------------------------------------------------------------------- + else if (userAction.equals("distSearch")) { + if (markX == 0 && markY == 0) + mapError = "No address or mark set"; + else if (!mv.getThemeEnabled(distSearchTheme)) + mapError = "Theme "+distSearchTheme+" is not visible"; + else if (distSearchParam <= 0) + mapError = "Enter search distance"; + else { + + // Construct point object from current location mark + JGeometry geom = new JGeometry(markX, markY, mapSrid); + + // Construct spatial query + String sqlQuery = "SELECT "+geoColumn+" FROM " + distSearchTheme + + " WHERE SDO_WITHIN_DISTANCE ("+ geoColumn + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'DISTANCE="+distSearchParam+" UNIT=M') = 'TRUE'"; + mapError = "Executing query: "+ sqlQuery; + + // Add a JDBC theme to highlight the results of the query + mv.addJDBCTheme ( + dataSource, // Data source + "SEARCH RESULTS", // Theme to search + sqlQuery, // SQL Query + geoColumn, // Name of spatial column + null, // srid + queryStyle, // renderStyle + null, // labelColumn + null, // labelStyle + true // passThrough + ); + + // Perform the query + String[][] f = mv.queryWithinRadius( + dataSource, // Data source + distSearchTheme, // Theme to search + colsToSelect, // Names of columns to select + null, // Extra condition + markX, markY, // Center point (current mark) + distSearchParam, // Distance to search + false // Center point is in ground coordinates + ); + + if (f!= null && f.length > 0) { + + // The result is one row per matching record, but we want to display + // results as one column per record. + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + + // Refresh map + mv.run(); + + } else + mapError = "No matching " + distSearchTheme + " found"; + + } + } + + // ----------------------------------------------------------------------- + // [nnSearch] button clicked + // Search the N nearest neighbors from the current set mark. + // ----------------------------------------------------------------------- + else if (userAction.equals("nnSearch")) { + if (markX == 0 && markY == 0) + mapError = "No address or mark set"; + else if (!mv.getThemeEnabled(nnSearchTheme)) + mapError = "Theme "+nnSearchTheme+" is not visible"; + else if (nnSearchParam <= 0) + mapError = "Enter number of matches to search"; + else { + + // Construct spatial query + String sqlQuery = "SELECT "+geoColumn+", SDO_NN_DISTANCE(1) DISTANCE" + + " FROM " + nnSearchTheme + + " WHERE SDO_NN ("+ geoColumn + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES="+nnSearchParam+"',1) = 'TRUE'" + + " ORDER BY DISTANCE"; + mapError = "Executing query: "+ sqlQuery; + + // Add a JDBC theme to highlight the results of the query + mv.addJDBCTheme ( + dataSource, // Data source + "SEARCH RESULTS", // Theme to search + sqlQuery, // SQL Query + geoColumn, // Name of spatial column + null, // srid + queryStyle, // renderStyle + null, // labelColumn + null, // labelStyle + true // passThrough + ); + + // Perform the query + String[][] f = mv.queryNN( + dataSource, // Data source + nnSearchTheme, // Theme to search + colsToSelect, // Names of columns to select + nnSearchParam, // Number of neighbors + markX, markY, // Center point (current mark) + null, // Extra condition + false, // Center point is in ground coordinates + null + ); + + if (f== null || f.length == 0) + mapError = "No matching " + nnSearchTheme + " found"; + else { + + // The result is one row per matching record, but we want to display + // results as one column per record. + featureInfo = new String[f[0].length][f.length]; + for (int i=0; i<f.length; i++) + for (int j=0; j<f[i].length; j++) + featureInfo[j][i] = f [i][j]; + featuresFound = f.length-1; + + // Remove any existing route + mv.removeAllLinearFeatures(); + + if (showRoute) { + + // Extract coordinates of destination node + double destX = Double.valueOf(f[1][numVisibleCols]).doubleValue(); + double destY = Double.valueOf(f[1][numVisibleCols+1]).doubleValue(); + + // Snap destination to nearest network node + String qd = "SELECT NODE_ID FROM " + net.getNodeTableName() + + " WHERE SDO_NN ("+net.getNodeGeomColumn() + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + destX + "," + destY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES=1') = 'TRUE'"; + String [][] sd = mv.doQuery(dataSource, qd); + int destNodeId = Integer.parseInt(sd[1][0]); + + // Snap start (mark) to nearest network node + String qs = "SELECT NODE_ID FROM " + net.getNodeTableName() + + " WHERE SDO_NN ("+net.getNodeGeomColumn() + "," + + " SDO_GEOMETRY (2001," + mapSrid + ", SDO_POINT_TYPE(" + + markX + "," + markY + ",NULL), NULL, NULL), " + + "'SDO_NUM_RES=1') = 'TRUE'"; + String [][] ss = mv.doQuery(dataSource, qs); + int startNodeId = Integer.parseInt(ss[1][0]); + + // Get path from mark to destination node + Path p = NetworkManager.shortestPath(net, startNodeId, destNodeId); + + // Check that we got a valid path back + if (p != null && p.getNoOfLinks() > 0) { + + // Compute path geometry + p.computeGeometry(0.5); + JGeometry g = p.getGeometry(); + + // Add route geometry to map + mv.addLinearFeature ( + g.getOrdinatesArray(), // Ordinates + mapSrid, // SRID + "L.TRANSPARENT", // Line style + null, // Label column + null // Label style + ); + + } else + mapError = "Unable to compute route"; + + } + + // Refresh map + mv.run(); + } + } + } + + // ----------------------------------------------------------------------- + // [Clear Search] button + // Clear search results + // ----------------------------------------------------------------------- + else if (userAction.equals("Clear Search")) { + + // Remove the markers of the matching results + mv.deleteTheme ("SEARCH RESULTS"); + + // Remove any route from the current mark + mv.removeAllLinearFeatures(); + + // Refresh map + mv.run(); + } + + // Update size and center on screen with new values + mapSize = mv.getSize(); + Point2D center = mv.getCenter(); + cx = center.getX(); + cy = center.getY(); + mapScale = mv.getMapScale(); + + // Get URL to generated Map + imgURL = mv.getGeneratedMapImageURL(); + + // Get the XML request sent to the server + mapRequest = mv.getMapRequestString(); + + // Get the XML response received from the server + mapResponse = mv.getMapResponseString(); + } + +%> + +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>Essential Guide to Oracle Spatial - Sample Application + + + + + + +
+
+ + + + + + + + + + + + + + + <% if (debug) { %> + + + + + + + + + <% } %> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Find address: +
+ +
+ + +

+ Location Mark: +
+ + + + + +
+ + + + + +
Longitude:<%= markX %>
Latitude: <%= markY %>
+
+ +
+

+ Search from Location Mark +
+ <% if (appThemes !=null && appThemes.length>0) {%> + + <% } %> + within + + meters + +
+ + +

+ Find nearest from Location Mark +
+ + nearest + <% if (appThemes !=null && appThemes.length>0) {%> + + <% } %> + +
+ Show route to nearest + + > +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + +
+ + + + +
+
+ + + + + +
+ Click on the map to: + > + Recenter + > + Identify + > + Mark +
+
+
+ + + + + + + + + + <% } %> + + + <% if (geocodeInfo !=null && geocodeInfo.length>0) {%> + + + <% } %> + + + +
+ <% String[] ts = mv.getThemeNames(); + if (ts != null) { %> + + + Select information to include on map + + + + + + +
+ + + + +
+ + <% for(int i=0; i + + <%}%> +
+ > + > + <%= ts[i] %> +
+
+ <%}%> +

+ + + <% if (featureInfo !=null && featureInfo.length>0) {%> +
Identification result(s): + <%= featuresFound %> match(es)
+ + <% for (int i=0; i + + <% String[] row = featureInfo[i]; + for (int k=0; k + + <% } %> + + <% } %> +
<%= row[k] %>
+
Address found: +
+ + <% for (int i=0; i + + <% } %> +
<%= geocodeInfo[i] %>
+
+
<%= mapError %>
+ + Data Source: <%= dataSource %>     + Map: <%= baseMap %>     + Network: <%= networkName %>     +
+ + Longitude: <%= cx %>   + Latitude: <%= cy %>   + Size: <%= mapSize %> + Scale: <%= mapScale %> +
XML Request:
+ +
XML Response:
+ +
+ + + + + + + + + + + diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-01.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-01.sql new file mode 100644 index 0000000..173a1c9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-01.sql @@ -0,0 +1,22 @@ +-- Listing 14-1. Correcting the Orientation of a Polygon Geometry Using TO_CURRENT +SELECT SDO_MIGRATE.TO_CURRENT + ( + SDO_GEOMETRY + ( + 2003, NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,1 ), + SDO_ORDINATE_ARRAY + ( + 2,2, -- Vertices specified in clockwise order + 3,3.5, + 5,2, + 2,2 + ) + ), + SDO_DIM_ARRAY + ( + SDO_DIM_ELEMENT('1', -180, 180, 0.0000005), + SDO_DIM_ELEMENT('2', -90, 90, 0.0000005) + ) + ) +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-02.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-02.sql new file mode 100644 index 0000000..99fbecd --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-02.sql @@ -0,0 +1,38 @@ +-- Listing 14-2. Correcting a Self-Crossing Polygon Geometry Using SDO_UNION +SELECT SDO_GEOM.SDO_UNION + ( + SDO_GEOMETRY -- self-crossing 'polygon' geometry + ( + 2003, -- A polygon type geometry: invalid because edges cross + NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,1 ), + SDO_ORDINATE_ARRAY + ( + 2,2, + 3,3.5, + 2,5, + 5,5, + 3,3.5, + 5,2, + 2,2 + ) + ), + SDO_GEOMETRY -- self-crossing 'polygon' geometry (repeated) + ( + 2003, + NULL, NULL, + SDO_ELEM_INFO_ARRAY(1,1003,1 ), + SDO_ORDINATE_ARRAY + ( + 2,2, + 3,3.5, + 2,5, + 5,5, + 3,3.5, + 5,2, + 2,2 + ) + ), + 0.0000005 + ) valid_gm +FROM DUAL; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-03.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-03.sql new file mode 100644 index 0000000..b541930 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-03.sql @@ -0,0 +1,5 @@ +-- Listing 14-3. Nearest-Neighbor Query on the customers Table +SELECT COUNT(*) + FROM branches a, customers b + WHERE a.id=1 + AND SDO_NN(b.location, a.location, 'SDO_NUM_RES=100')='TRUE'; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-04.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-04.sql new file mode 100644 index 0000000..1511b37 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-04.sql @@ -0,0 +1,3 @@ +-- Listing 14-4. Specifying LAYER_GTYPE During Spatial Index Creation +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX PARAMETERS('LAYER_GTYPE=POINT'); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-05.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-05.sql new file mode 100644 index 0000000..2cc53cc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-05.sql @@ -0,0 +1,4 @@ +-- Listing 14-5. Creating an Empty Table with the Same Structure As the us_streets Table +CREATE TABLE us_streets_dup AS SELECT * FROM us_streets; +TRUNCATE TABLE us_streets; +DROP INDEX us_streets_sidx; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-06.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-06.sql new file mode 100644 index 0000000..adaa997 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-06.sql @@ -0,0 +1,13 @@ +-- Listing 14-6. Reinserting into the us_streets Table Based on the linear_key Order +INSERT INTO us_streets + SELECT * + FROM us_streets_dup a + ORDER BY + linear_key + ( + a.location, + ( + SELECT diminfo FROM USER_SDO_GEOM_METADATA + WHERE table_name = 'US_STREETS' AND column_name='LOCATION' + ) + ); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-07.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-07.sql new file mode 100644 index 0000000..4c3f09f --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-07.sql @@ -0,0 +1,26 @@ +-- Listing 14-7. Using the linear_key Function to Order Geometry Rows Based on a 'Spatial' Ordering +CREATE OR REPLACE FUNCTION linear_key +( + location SDO_GEOMETRY, + diminfo SDO_DIM_ARRAY +) +RETURN RAW DETERMINISTIC +IS + ctr SDO_GEOMETRY; + rval RAW(48); + lvl INTEGER; +BEGIN + + -- Compute the centroid of the geometry + -- Alternately, you can use the 'faster' sdo_pointonsurface function + ctr := SDO_GEOM.SDO_CENTROID(location, diminfo); + lvl := 8; -- Specifies the encoding level for hhcode function + rval := + MD.HHENCODE + ( -- Specify value, lower and upper bounds, encoding level for each dimension + location.sdo_point.x, diminfo(1).sdo_lb, diminfo(1).sdo_ub, lvl, + location.sdo_point.y, diminfo(2).sdo_lb, diminfo(2).sdo_ub, lvl + ); + RETURN rval; +END; +/ diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-08.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-08.sql new file mode 100644 index 0000000..3673981 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-08.sql @@ -0,0 +1,3 @@ +-- Listing 14-8. Aggregate Union of All Geometries in the us_counties Table +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(a.geom, 0.5)) union_geom +FROM us_counties a; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-09.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-09.sql new file mode 100644 index 0000000..0bedd6c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-09.sql @@ -0,0 +1,5 @@ +-- Listing 14-9. Computing the Aggregate Unions for Multiple Groups +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(geom, 0.5)), SUBSTR(county,1,1) + FROM us_counties + WHERE state_abrv='MA' + GROUP BY (SUBSTR(county,1,1)); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-10.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-10.sql new file mode 100644 index 0000000..8adf809 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-10.sql @@ -0,0 +1,5 @@ +-- Listing 14-10. Computing the Aggregate Unions Grouped by the ROWNUM Pseudo Column +SELECT SDO_AGGR_UNION(sdoaggrtype(geom, 0.5)) union_geom + FROM us_counties + WHERE state_abrv='MA' + GROUP BY MOD(ROWNUM,10); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-11.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-11.sql new file mode 100644 index 0000000..ee0c1f9 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-11.sql @@ -0,0 +1,9 @@ +-- Listing 14-11. Computing the Aggregate Union of Aggregate Unions Grouped by the ROWNUM Pseudo-Column +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(union_geom, 0.5)) + FROM + ( + SELECT SDO_AGGR_UNION(SDOAGGRTYPE(geom, 0.5)) union_geom + FROM us_counties + WHERE state_abrv='MA' + GROUP BY MOD(ROWNUM,10) +); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-12.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-12.sql new file mode 100644 index 0000000..0ec8a15 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-12.sql @@ -0,0 +1,18 @@ +-- Listing 14-12. Computing the Aggregate Union in a Pipelined Fashion +SELECT SDO_AGGR_UNION(SDOAGGRTYPE(ugeom,0.5)) ugeom +FROM +( + SELECT SDO_AGGR_UNION(SDOAGGRTYPE(ugeom,0.5)) ugeom + FROM + ( + SELECT SDO_AGGR_UNION(SDOAGGRTYPE(ugeom,0.5)) ugeom + FROM + ( + SELECT SDO_AGGR_UNION(SDOAGGRTYPE(geom,0.5)) ugeom + FROM us_counties + GROUP BY MOD (ROWNUM, 1000) + ) + GROUP BY MOD (ROWNUM, 100) + ) + GROUP BY MOD (ROWNUM, 10) +); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-13.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-13.sql new file mode 100644 index 0000000..0d70544 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-13.sql @@ -0,0 +1,4 @@ +-- Listing 14-13. Setting the SDO_DML_BATCH_SIZE Parameter +CREATE INDEX customers_sidx ON customers(location) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + PARAMETERS('SDO_DML_BATCH_SIZE=5000'); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-14.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-14.sql new file mode 100644 index 0000000..9edd7dc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-14.sql @@ -0,0 +1,18 @@ +-- Listing 14-14. Creating a Partitioned Table for Storing Temporal Weather Pattern Data +CREATE TABLE weather_patterns +( + gid NUMBER, + geom SDO_GEOMETRY, + creation_date VARCHAR2(32) +) +PARTITION BY RANGE(CREATION_DATE) +( + PARTITION p1 VALUES LESS THAN ('2000-01-01') TABLESPACE tbs_3, + PARTITION p2 VALUES LESS THAN ('2001-01-01') TABLESPACE tbs_3, + PARTITION p3 VALUES LESS THAN ('2002-01-01') TABLESPACE tbs_3, + PARTITION p4 VALUES LESS THAN ('2003-01-01') TABLESPACE tbs_3, + PARTITION p5 VALUES LESS THAN ('2004-01-01') TABLESPACE tbs_3, + PARTITION jan VALUES LESS THAN ('2004-02-01'), -- Month of January, 2004 + PARTITION feb VALUES LESS THAN ('2004-03-01'), -- Month of February, 2004 + PARTITION current_month VALUES LESS THAN (MAXVALUE) +); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-15.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-15.sql new file mode 100644 index 0000000..3165f81 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-15.sql @@ -0,0 +1,15 @@ + +-- Insert metadata +INSERT INTO USER_SDO_GEOM_METADATA VALUES +('WEATHER_PATTERNS', 'GEOM', + SDO_DIM_ARRAY( + SDO_DIM_ELEMENT('LONG', -180, 180, 0.5), + SDO_DIM_ELEMENT('LAT', -90, 90, 0.5) + ), + 8307 +); + +-- Listing 14-15. Creating a Local Partitioned Spatial Index +CREATE INDEX weather_patterns_sidx ON weather_patterns(geom) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + LOCAL; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-16.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-16.sql new file mode 100644 index 0000000..7986679 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-16.sql @@ -0,0 +1,5 @@ +-- Listing 14-16. Creating a Local Partitioned Spatial Index As 'Unusable' +CREATE INDEX weather_patterns_sidx ON weather_patterns(geom) + INDEXTYPE IS MDSYS.SPATIAL_INDEX + LOCAL + UNUSABLE; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-17.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-17.sql new file mode 100644 index 0000000..6c73b9c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-17.sql @@ -0,0 +1,2 @@ +-- Listing 14-17. Rebuilding a Local Spatial Index +ALTER INDEX weather_patterns_sidx REBUILD PARTITION P1; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-18.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-18.sql new file mode 100644 index 0000000..050158c --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-18.sql @@ -0,0 +1,2 @@ +-- Listing 14-18. Rebuilding All UNUSABLE Indexes for a Table Partition +ALTER TABLE weather_patterns MODIFY PARTITION P1 REBUILD UNUSABLE LOCAL INDEXES; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-19.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-19.sql new file mode 100644 index 0000000..bab2b04 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-19.sql @@ -0,0 +1,3 @@ +-- Listing 14-19. Exchanging tmp Data with Partition p1 of weather_patternsWithout Indexes +ALTER TABLE weather_patterns + EXCHANGE PARTITION current_month WITH TABLE tmp EXCLUDING INDEXES; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-20.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-20.sql new file mode 100644 index 0000000..b746019 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-20.sql @@ -0,0 +1,9 @@ +-- Listing 14-20. Adding New Data Using the EXCHANGE PARTITION Clause +CREATE TABLE tmp (gid number, geom sdo_geometry, date varcahr2(32)); +INSERT INTO TABLE tmp VALUES (...); --- new data +-- Also include data from current_month partition +INSERT INTO TABLE tmp + SELECT * FROM weather_partitions PARTITION(current_month); +-- Exchange table tmp with "current_month" partition of weather_patterns. +ALTER TABLE weather_patterns +EXCHANGE PARTITION current_month WITH TABLE tmp INCLUDING INDEXES; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-21.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-21.sql new file mode 100644 index 0000000..d604391 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-21.sql @@ -0,0 +1,7 @@ +-- Listing 14-21. Splitting the current_month Partition into march and current_month Partitions +ALTER TABLE weather_patterns + SPLIT PARTITION current_month AT ('2004-04-1') INTO + ( + PARTITION march, + PARTITION current_month + ); diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-22.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-22.sql new file mode 100644 index 0000000..c9838bc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-22.sql @@ -0,0 +1,3 @@ +-- Listing 14-22. Rebuilding the Indexes for the 'Split' Partitions +ALTER INDEX weather_patterns_sidx REBUILD PARTITION march; +ALTER INDEX weather_patterns_sidx REBUILD PARTITION current_month; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-23.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-23.sql new file mode 100644 index 0000000..9e498ec --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-23.sql @@ -0,0 +1,3 @@ +-- Listing 14-23. Merging the Partitions for jan and feb into a Single Partition +ALTER TABLE weather_patterns + MERGE PARTITIONS jan, feb INTO PARTITION janfeb; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-24.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-24.sql new file mode 100644 index 0000000..6300c01 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-24.sql @@ -0,0 +1,2 @@ +-- Listing 14-24. Renaming a Partition +ALTER INDEX weather_patterns_sidx RENAME PARTITION janfeb TO jan; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-25.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-25.sql new file mode 100644 index 0000000..a988e49 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-25.sql @@ -0,0 +1,2 @@ +-- Listing 14-25. Renaming the Merged Monthly Partition As a Year Partition +ALTER INDEX weather_patterns_sidx RENAME PARTITION jan TO p2004; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-26.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-26.sql new file mode 100644 index 0000000..d110815 --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-26.sql @@ -0,0 +1,2 @@ +-- Listing 14-26. Setting the location Column in the customers Table to a NULLValue +UPDATE customers SET location = NULL; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-27.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-27.sql new file mode 100644 index 0000000..df3dccc --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-27.sql @@ -0,0 +1,4 @@ +-- Listing 14-27. Determining the SRIDValue in the Location (Geometry) Columns of a Table +SELECT a.location.sdo_srid +FROM customers a +WHERE ROWNUM=1; diff --git a/ProOracleSpatialCode/Code/Chapter-14/listing-14-28.sql b/ProOracleSpatialCode/Code/Chapter-14/listing-14-28.sql new file mode 100644 index 0000000..9308b2d --- /dev/null +++ b/ProOracleSpatialCode/Code/Chapter-14/listing-14-28.sql @@ -0,0 +1,5 @@ +-- Listing 14-28. Determining the SRIDValue for a Spatial Layer (Specified by table_name, column_name) +SELECT srid +FROM USER_SDO_GEOM_METADATA +WHERE table_name='CUSTOMERS' +AND column_name='LOCATION'; diff --git a/ProOracleSpatialCode/Data/loading/appendix-a-import.bat b/ProOracleSpatialCode/Data/loading/appendix-a-import.bat new file mode 100644 index 0000000..d64692d --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/appendix-a-import.bat @@ -0,0 +1 @@ +imp spatial/spatial file=zip.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/appendix-a-import.txt b/ProOracleSpatialCode/Data/loading/appendix-a-import.txt new file mode 100644 index 0000000..d64692d --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/appendix-a-import.txt @@ -0,0 +1 @@ +imp spatial/spatial file=zip.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-02-import.bat b/ProOracleSpatialCode/Data/loading/chapter-02-import.bat new file mode 100644 index 0000000..e03b9b1 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-02-import.bat @@ -0,0 +1,3 @@ +imp spatial/spatial file=gc.dmp full=y +imp spatial/spatial file=map_large.dmp tables=us_interstates +imp spatial/spatial file=map_detailed.dmp tables=us_restaurants diff --git a/ProOracleSpatialCode/Data/loading/chapter-02-import.txt b/ProOracleSpatialCode/Data/loading/chapter-02-import.txt new file mode 100644 index 0000000..e03b9b1 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-02-import.txt @@ -0,0 +1,3 @@ +imp spatial/spatial file=gc.dmp full=y +imp spatial/spatial file=map_large.dmp tables=us_interstates +imp spatial/spatial file=map_detailed.dmp tables=us_restaurants diff --git a/ProOracleSpatialCode/Data/loading/chapter-03-import.bat b/ProOracleSpatialCode/Data/loading/chapter-03-import.bat new file mode 100644 index 0000000..3fa4655 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-03-import.bat @@ -0,0 +1 @@ +imp spatial/spatial file=gc.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-03-import.txt b/ProOracleSpatialCode/Data/loading/chapter-03-import.txt new file mode 100644 index 0000000..3fa4655 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-03-import.txt @@ -0,0 +1 @@ +imp spatial/spatial file=gc.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-04-import.bat b/ProOracleSpatialCode/Data/loading/chapter-04-import.bat new file mode 100644 index 0000000..9302401 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-04-import.bat @@ -0,0 +1 @@ +imp spatial/spatial file=map_large.dmp tables=(us_interstates,us_states) diff --git a/ProOracleSpatialCode/Data/loading/chapter-04-import.txt b/ProOracleSpatialCode/Data/loading/chapter-04-import.txt new file mode 100644 index 0000000..9302401 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-04-import.txt @@ -0,0 +1 @@ +imp spatial/spatial file=map_large.dmp tables=(us_interstates,us_states) diff --git a/ProOracleSpatialCode/Data/loading/chapter-05-import.bat b/ProOracleSpatialCode/Data/loading/chapter-05-import.bat new file mode 100644 index 0000000..ad97008 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-05-import.bat @@ -0,0 +1 @@ +imp spatial/spatial file=app_with_loc.dmp full=y indexes=n diff --git a/ProOracleSpatialCode/Data/loading/chapter-05-import.txt b/ProOracleSpatialCode/Data/loading/chapter-05-import.txt new file mode 100644 index 0000000..ad97008 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-05-import.txt @@ -0,0 +1 @@ +imp spatial/spatial file=app_with_loc.dmp full=y indexes=n diff --git a/ProOracleSpatialCode/Data/loading/chapter-06-import.bat b/ProOracleSpatialCode/Data/loading/chapter-06-import.bat new file mode 100644 index 0000000..30ed870 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-06-import.bat @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_data.dmp full=y +imp spatial/spatial file=gc.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-06-import.txt b/ProOracleSpatialCode/Data/loading/chapter-06-import.txt new file mode 100644 index 0000000..30ed870 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-06-import.txt @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_data.dmp full=y +imp spatial/spatial file=gc.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-07-import.bat b/ProOracleSpatialCode/Data/loading/chapter-07-import.bat new file mode 100644 index 0000000..99bc296 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-07-import.bat @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-07-import.txt b/ProOracleSpatialCode/Data/loading/chapter-07-import.txt new file mode 100644 index 0000000..99bc296 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-07-import.txt @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-08-import.bat b/ProOracleSpatialCode/Data/loading/chapter-08-import.bat new file mode 100644 index 0000000..f025733 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-08-import.bat @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y indexes=n +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-08-import.txt b/ProOracleSpatialCode/Data/loading/chapter-08-import.txt new file mode 100644 index 0000000..f025733 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-08-import.txt @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y indexes=n +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-09-import.bat b/ProOracleSpatialCode/Data/loading/chapter-09-import.bat new file mode 100644 index 0000000..99bc296 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-09-import.bat @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-09-import.txt b/ProOracleSpatialCode/Data/loading/chapter-09-import.txt new file mode 100644 index 0000000..99bc296 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-09-import.txt @@ -0,0 +1,2 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-10-import.bat b/ProOracleSpatialCode/Data/loading/chapter-10-import.bat new file mode 100644 index 0000000..007be23 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-10-import.bat @@ -0,0 +1 @@ +imp spatial/spatial file=net.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-10-import.sql b/ProOracleSpatialCode/Data/loading/chapter-10-import.sql new file mode 100644 index 0000000..1f345ca --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-10-import.sql @@ -0,0 +1,4 @@ +-- Load network metadata and map definitions +insert into user_sdo_network_metadata + select * from my_network_metadata; +commit; diff --git a/ProOracleSpatialCode/Data/loading/chapter-10-import.txt b/ProOracleSpatialCode/Data/loading/chapter-10-import.txt new file mode 100644 index 0000000..007be23 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-10-import.txt @@ -0,0 +1 @@ +imp spatial/spatial file=net.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-11-import.bat b/ProOracleSpatialCode/Data/loading/chapter-11-import.bat new file mode 100644 index 0000000..ecadf56 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-11-import.bat @@ -0,0 +1,4 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y +imp spatial/spatial file=map_detailed.dmp full=y +imp spatial/spatial file=styles.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-11-import.sql b/ProOracleSpatialCode/Data/loading/chapter-11-import.sql new file mode 100644 index 0000000..3c75d42 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-11-import.sql @@ -0,0 +1,8 @@ +-- Load map definitions +insert into user_sdo_styles + select * from my_styles; +insert into user_sdo_themes + select * from my_themes; +insert into user_sdo_maps + select * from my_maps; +commit; diff --git a/ProOracleSpatialCode/Data/loading/chapter-11-import.txt b/ProOracleSpatialCode/Data/loading/chapter-11-import.txt new file mode 100644 index 0000000..ecadf56 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-11-import.txt @@ -0,0 +1,4 @@ +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=map_large.dmp full=y +imp spatial/spatial file=map_detailed.dmp full=y +imp spatial/spatial file=styles.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-12-import.bat b/ProOracleSpatialCode/Data/loading/chapter-12-import.bat new file mode 100644 index 0000000..acca562 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-12-import.bat @@ -0,0 +1,7 @@ +imp spatial/spatial file=app_data.dmp full=y +imp spatial/spatial file=gc.dmp full=y +imp spatial/spatial file=map_detailed.dmp full=y +imp spatial/spatial file=map_large.dmp full=y +imp spatial/spatial file=net.dmp full=y +imp spatial/spatial file=setup.txt full=y +imp spatial/spatial file=styles.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/chapter-12-import.sql b/ProOracleSpatialCode/Data/loading/chapter-12-import.sql new file mode 100644 index 0000000..969d5fd --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-12-import.sql @@ -0,0 +1,26 @@ +-- Load network metadata and map definitions +insert into user_sdo_network_metadata + select * from my_network_metadata; +commit; + +-- Load map definitions +insert into user_sdo_styles + select * from my_styles; +insert into user_sdo_themes + select * from my_themes; +insert into user_sdo_maps + select * from my_maps; +commit; + +-- Create PL/SQL tools +create or replace function get_point_x(g sdo_geometry) return number is +begin + return g.sdo_point.x; +end; +/ +create or replace function get_point_y(g sdo_geometry) return number is +begin + return g.sdo_point.y; +end; +/ + diff --git a/ProOracleSpatialCode/Data/loading/chapter-12-import.txt b/ProOracleSpatialCode/Data/loading/chapter-12-import.txt new file mode 100644 index 0000000..acca562 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/chapter-12-import.txt @@ -0,0 +1,7 @@ +imp spatial/spatial file=app_data.dmp full=y +imp spatial/spatial file=gc.dmp full=y +imp spatial/spatial file=map_detailed.dmp full=y +imp spatial/spatial file=map_large.dmp full=y +imp spatial/spatial file=net.dmp full=y +imp spatial/spatial file=setup.txt full=y +imp spatial/spatial file=styles.dmp full=y diff --git a/ProOracleSpatialCode/Data/loading/copy.bat b/ProOracleSpatialCode/Data/loading/copy.bat new file mode 100644 index 0000000..0b363bf --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/copy.bat @@ -0,0 +1,25 @@ +touch chapter-02-import.bat +touch chapter-03-import.bat +touch chapter-04-import.bat +touch chapter-05-import.bat +touch chapter-06-import.bat +touch chapter-07-import.bat +touch chapter-08-import.bat +touch chapter-09-import.bat +touch chapter-10-import.bat +touch chapter-11-import.bat +touch chapter-12-import.bat +touch appendix-a-import.bat + +cp chapter-02-import.bat chapter-02-import.txt +cp chapter-03-import.bat chapter-03-import.txt +cp chapter-04-import.bat chapter-04-import.txt +cp chapter-05-import.bat chapter-05-import.txt +cp chapter-06-import.bat chapter-06-import.txt +cp chapter-07-import.bat chapter-07-import.txt +cp chapter-08-import.bat chapter-08-import.txt +cp chapter-09-import.bat chapter-09-import.txt +cp chapter-10-import.bat chapter-10-import.txt +cp chapter-11-import.bat chapter-11-import.txt +cp chapter-12-import.bat chapter-12-import.txt +cp appendix-a-import.bat appendix-a-import.txt diff --git a/ProOracleSpatialCode/Data/loading/setup.txt b/ProOracleSpatialCode/Data/loading/setup.txt new file mode 100644 index 0000000..2dd88c4 --- /dev/null +++ b/ProOracleSpatialCode/Data/loading/setup.txt @@ -0,0 +1,41 @@ +1. Create user SPATIAL + +create user spatial identified by spatial; +grant resource, connect to spatial; + +2. Import all data sets + +imp spatial/spatial file=app_with_loc.dmp full=y +imp spatial/spatial file=gc.dmp full=y +imp spatial/spatial file=map_detailed.dmp full=y +imp spatial/spatial file=map_large.dmp full=y +imp spatial/spatial file=net.dmp full=y +imp spatial/spatial file=styles.dmp full=y +imp spatial/spatial file=zip.dmp full=y + +3. Load network metadata and map definitions + +insert into user_sdo_network_metadata + select * from my_network_metadata; +commit; + +insert into user_sdo_styles + select * from my_styles; +insert into user_sdo_themes + select * from my_themes; +insert into user_sdo_maps + select * from my_maps; +commit; + +4. Create PL/SQL tools + +create or replace function get_point_x(g sdo_geometry) return number is +begin + return g.sdo_point.x; +end; +/ +create or replace function get_point_y(g sdo_geometry) return number is +begin + return g.sdo_point.y; +end; +/ diff --git a/ProOracleSpatialCode/about.shtml b/ProOracleSpatialCode/about.shtml new file mode 100644 index 0000000..d1850fa --- /dev/null +++ b/ProOracleSpatialCode/about.shtml @@ -0,0 +1,38 @@ + + + + + +

About the Authors

+
+ + + + + + + + + + + +
+RAVI KOTHURI holds a Ph.D. in computer science from the University of California, Santa Barbara, and has worked in spatial and multimedia research and development for the past 10 years. Currently, he serves as a principal member in the spatial development team of Oracle Corporation. He is responsible for several patented features in Oracle Spatial and has authored numerous articles for database conferences and journals. Ravi enjoys music, movies, and playing with his children in his spare time.
+
+
+ALBERT GODFRIND has over 25 +years of experience in designing, developing, and deploying IT applications. His interest and enthusiasm for spatial information and geographical information systems started at Oracle when he discovered the spatial extensions of the Oracle database in 1998. +Ever since, Albert has been “evangelizing” the use of spatial information +both to GIS and IT communities across Europe, consulting with partners and customers, speaking at conferences, and designing and delivering +in-depth technical training. Prior to joining Oracle Corporation, Albert held several positions in database engineering at Digital Equipment Corporation (DEC), where he worked on the development of the Rdb database system.
+
+
+EURO BEINAT holds a Ph.D. in +economics and a master’s degree in electronics and systems engineering. He has been involved in consultancy for over 10 years in evaluation and strategic advice in sectors ranging from IT, government, the oil industry, and large corporations. At present, he is +the managing director of Geodan Mobile Solutions and holds a chair at the Vrije Universiteit of Amsterdam as director of the spatial information +laboratory. His main skills combine geo-IT and the Internet, with an extensive competence in decision analysis and strategy.
+
+
+ + + diff --git a/ProOracleSpatialCode/code.html b/ProOracleSpatialCode/code.html new file mode 100644 index 0000000..cb8c900 --- /dev/null +++ b/ProOracleSpatialCode/code.html @@ -0,0 +1,432 @@ + + + +Essential Guide To Oracle Spatial - Code Examples + + +

Essential Guide To Oracle Spatial - Code Examples

+Goto chapter: +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +A +B +C +D + +

Chapter 1 - Introduction to Spatial Processing

+ +

Chapter 2 - Location-enabling your application

+ + + + + + + + + + +
ListingDescriptionFile Name
2-1Creating the us_restaurants_new Tablelisting-02-01.sql
2-2Inserting a Value for the SDO_GEOMETRY Column in an Oracle Tablelisting-02-02.sql
2-3Converting Address Data (Implicit Spatial Information) to the SDO_GEOMETRY (Explicit Spatial Information) Objectlisting-02-03.sql
2-4Finding the Five Nearest Restaurants on I-795listing-02-04.sql
2-5Creating an Index on Locations (SDO_GEOMETRY Column) of Restaurantslisting-02-05.sql
2-6Finding the Five Nearest Restaurants on Interstate I-795 Using the Spatial Indexlisting-02-06.sql
2-7Identifying All Restaurants in a 50 km Radius Around Interstate I-795listing-02-07.sql
2-8Verifying That a Spatial Install Is Successfullisting-02-08.sql
+ +

Chapter 3 - The SDO_GEOMETRY Data Type

+ + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
3-1Creating the customers Tablelisting-03-01.sql
3-2Populating customers table.listing-03-02.sql
3-3Adding a location Column to the customers Tablelisting-03-03.sql
3-4Sample Address for a Specific Customer in the customers Tablelisting-03-04.sql
3-5Geocoding Addresses to Obtain Explicit Spatial Informationlisting-03-05.sql
3-6Geocoded location Column in the customers Tablelisting-03-06.sql
3-7Updating a location Column Using an SDO_GEOMETRY Constructorlisting-03-07.sql
3-8Creating the us_states Tablelisting-03-08.sql
3-9Creating the us_counties Tablelisting-03-09.sql
3-10Creating the us_interstates Tablelisting-03-10.sql
3-11The USER_SDO_GEOM_METADATA Viewlisting-03-11.sql
3-12Selecting srids of Geodetic Coordinate Systems.listing-03-12.sql
3-13Selecting srids of Projected Coordinate Systems.listing-03-13.sql
3-14The SDO_DIM_ARRAY Structurelisting-03-14.sql
3-15Inserting Metadata for the Spatial Layer Corresponding to the location Column of the customers Tablelisting-03-15.sql
+ +

Chapter 4 - Location-enabling your application

+ + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
4-1Creating a table to store all geometry exampleslisting-04-01.sql
4-2SDO_GEOMETRY Data type in Oraclelisting-04-02.sql
4-3Example of SDO_GTYPE in the location column of customers table.listing-04-03.sql
4-4Example of SDO_GTYPE in the geom Column of us_interstates tablelisting-04-04.sql
4-5Example of SDO_GTYPE in the location column of us_states table.listing-04-05.sql
4-6Example of SDO_GTYPE in the location column of us_states table.listing-04-06.sql
4-7The MDSYS.CS_SRS Tablelisting-04-07.sql
4-8Selecting an SRID for the Southern Texas Region from the MDSYS.CS_SRS Tablelisting-04-08.sql
4-9SDO_POINT_TYPE Data Typelisting-04-09.sql
4-10Point Data in geometry_exampleslisting-04-10.sql
4-11Constructing a Point Geometry Using Well-Known Text (SQL/MM)listing-04-11.sql
4-12Storing the Point Coordinates in the SDO_ORDINATES Array Instead of SDO_POINTlisting-04-12.sql
4-13Four-Dimensional Point Examplelisting-04-13.sql
4-14Two-Dimensional Line String Examplelisting-04-14.sql
4-15Two-Dimensional Line String Connected by Arcslisting-04-15.sql
4-16Example of a Simple Polygon Connected by Lineslisting-04-16.sql
4-17Rectangular Polygon Examplelisting-04-17.sql
4-18Circular Polygon Examplelisting-04-18.sql
+ +

Chapter 5 - Loading and Validating Spatial Data

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
5-1Creating the sales_regions Tablelisting-05-01.sql
5-2Inserting a Polygon Geometry into the sales_regions Tablelisting-05-02.sql
5-3Control File for Loading "Point" sales_regions Datalisting-05-03.ctl
5-4Using SQL*Loader to Load Data into the sales_regions Tablelisting-05-04.bat
5-5Using SQL*Loader with a Data Filelisting-05-05.bat
5-6sales_regions.ctl Filelisting-05-06.ctl
5-8Control File for Loading Nonpoint SDO_GEOMETRY Datalisting-05-08.ctl
5-9Exporting the customers Table into the customers.dmp Filelisting-05-09.bat
5-10Importing the customers Table into the scott Schemalisting-05-10.bat
5-11Importing Using the fromuser and touser Argumentslisting-05-11.bat
5-12Transporting the Tablespace TBS from a Source Databaselisting-05-12.bat
5-13Creating the Transported Tablespace in the Target Databaselisting-05-13.bat
5-14Enabling Spatial Indexes for the Tables in the Transported Tablespacelisting-05-14.bat
5-15Rebuilding a Spatial Index After Transporting Across Endian Platformslisting-05-15.sql
5-16Migrating location Column Data in the customers Table to the Current Format (10g)listing-05-16.sql
5-17Using shp2sdo to Convert from ESRI Shapefileslisting-05-17.bat
5-18customers.sql Filelisting-05-18.sql
5-19Executing the Output Files from SHP2SDO to Load Data into Oraclelisting-05-19.bat
5-20Converting from an SDO_GEOMETRY to WKT Formatlisting-05-20.sql
5-21Publishing an SDO_GEOMETRY to a GML Documentlisting-05-21.sql
5-22Publishing Multiple Geometries to a GML Document Fragmentlisting-05-22.sql
5-24Validation Check on a Geometry from the sales_regions Tablelisting-05-24.sql
5-25Validation on a Self-Crossing Geometrylisting-05-25.sql
5-26Using the diminfo Parameter in the VALIDATE_GEOMETRY_WITH_CONTEXT Functionlisting-05-26.sql
5-28Using the VALIDATE_LAYER_WITH_CONTEXT Procedurelisting-05-28.sql
5-29Example of Removing Duplicate Vertices in a Geometrylisting-05-29.sql
5-30Validating After Removing the Duplicate Verticeslisting-05-30.sql
5-31Extracting the Second Element from a Geometrylisting-05-31.sql
5-32Validation of an Extracted Geometrylisting-05-32.sql
5-33Validation on the Result of SDO_UTIL.EXTRACTlisting-05-33.sql
5-34Removing Duplicate Verticeslisting-05-34.sql
5-35Example of SDO_UTIL.APPENDlisting-05-35.sql
5-36Finding the Number of Elements in a Geometrylisting-05-36.sql
+ +

Chapter 6 - Geocoding

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
6-1Geocoding an Addresslisting-06-01.sql
6-2Geocoding and Normalizing an Addresslisting-06-02.sql
6-3Using the GEOCODE_AS_GEOMETRY Functionlisting-06-03.sql
6-4Using the GEOCODE_AS_GEOMETRY Function with an Invalid House Numberlisting-06-04.sql
6-5Using the GEOCODE_AS_GEOMETRY Function with an Invalid Street Namelisting-06-05.sql
6-6Example of Calling the GEOCODE Functionlisting-06-06.sql
6-7FORMAT_GEO_ADDR Procedurelisting-06-07.sql
6-8Example of Using the FORMAT_GEO_ADDR Procedurelisting-06-08.sql
6-9Getting Street Details from the Geocode Reference Datalisting-06-09.sql
6-10Using the GEOCODE Function with aValid House Numberlisting-06-10.sql
6-11Using the GEOCODE Function with an Invalid House Numberlisting-06-11.sql
6-12Using the GEOCODE Function with an Invalid Postal Codelisting-06-12.sql
6-13Using the GEOCODE Function with an Invalid Postal Code (in EXACTMode)listing-06-13.sql
6-14Using the GEOCODE Function to Find a POIlisting-06-14.sql
6-15FORMAT_ADDR_ARRAY Procedurelisting-06-15.sql
6-16Using GEOCODE_ALL over an Ambiguous Addresslisting-06-16.sql
6-17Using GEOCODE_ALL over an Ambiguous Addresslisting-06-17.sql
6-18Adding a Spatial Columnlisting-06-18.sql
6-19Populating the location Column of the branches Tablelisting-06-19.sql
6-20Populating the location Column of the branches Table for German Addresseslisting-06-20.sql
6-21Address Geocoding and Correctionlisting-06-21.sql
6-22Automatic Geocoding of the branches Table Using a Simple Triggerlisting-06-22.sql
6-23Automatic Geocoding with Address Correctionlisting-06-23.sql
+ +

Chapter 7 - Using the SDO_GEOMETRY type in applications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
7-1Extracting Coordinateslisting-07-01.sql
7-2Simple Spatial Querylisting-07-02.sql
7-3Sample Application in PL/SQLlisting-07-03.sql
7-4Manipulating VARRAYslisting-07-04.sql
7-5Point Constructor Functionlisting-07-05.sql
7-6Rectangle Constructorlisting-07-06.sql
7-7Line Constructorlisting-07-07.sql
7-8Counting the Number of Points in a Geometrylisting-07-08.sql
7-9Function to Extract a Point from a Geometrylisting-07-09.sql
7-10Getting the First,Middle, and Last Points of a Line Stringlisting-07-10.sql
7-11remove_point Functionlisting-07-11.sql
7-12Adding a Point in a Line String (add_to_line in Listing 7-3)listing-07-12.sql
7-14Invoking SdoPrintlisting-07-14.bat
N/AUsing the Java API for reading geometriesSdoPrint.java
N/AUsing the Java API for creating and updating geometriesSdoLoad.java
N/AThis program illustrates the basic operation of an OCI program. It does not use any spatial concepts; it just fetches regular column data from the US_CITIES table.oci_sample.c
N/ASame, illustrating the use of array fetches (the size of the array is passed as the last command-line argument).oci_sample_array.c
N/AIllustrates the fetching of spatial information (points) without using object types (i.e., by extracting the x and y values of each point).read_points.c
N/ASame, using array fetchesread_points_array.c
N/AComplete example of how to read and decode geometry objects.read_geom.c
N/ASame, using array fetchesread_geom_array.c
N/ASelect spatial objects using a spatial query.select_pois.c
N/ALoads geometry objects into a table in the database. The geometries are read from a text file.load_geom.c
N/ARead geometries in Pro*Cpreadgeom.pc
N/AWrite geometries in Pro*Cpwritegeom.pc
+ +

Chapter 8 - Spatial Indexes and Operators

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
8-1SDO_WITHIN_DISTANCE Spatial Operator in SQLlisting-08-01.sql
8-2Creating an Indexlisting-08-02.sql
8-3USER_SDO_GEOM_METADATA Viewlisting-08-03.sql
8-4Inserting Metadata for the Spatial Layer Corresponding to the location Column of the customers Tablelisting-08-04.sql
8-5Dropping a Spatial Indexlisting-08-05.sql
8-6Creating a Spatial Index on the location Column of the customers Tablelisting-08-06.sql
8-7Identifying the SDO_INDEX_TABLE That Stores the Spatial Index on the customers Tablelisting-08-07.sql
8-9Creating a Spatial Index in Tablespace TBS_3listing-08-09.sql
8-10Creating an Index with the INITIAL and NEXT Extents for an Index Tablelisting-08-10.sql
8-11Creating an Index with WORK_TABLESPACE As TBS_3listing-08-11.sql
8-12Creating an Index for Specific-Type (Point) Geometrieslisting-08-12.sql
8-13Creating an R-tree Index with Dimensionality Specifiedlisting-08-13.sql
8-14Creating an Index with the SDO_DML_BATCH_SIZE Parameterlisting-08-14.sql
8-15Creating a Quadtree Type of Spatial Indexlisting-08-15.sql
8-16Examining the USER_SDO_INDEX_METADATAView for Index Parameterslisting-08-16.sql
8-17Estimating the Size of a Spatial Index on the location Column of the customers Tablelisting-08-17.sql
8-19Spatial Operator Usage in a SQL Statementlisting-08-19.sql
8-20SDO_WITHIN_DISTANCE Operator Retrieving All Customers Within a Quarter-Mile Radius of a Competitor Storelisting-08-20.sql
8-21SDO_WITHIN_DISTANCE Operator Retrieving All Customers in a Quarter-Mile Radius of a Competitor Store and Also Reporting Their Distanceslisting-08-21.sql
8-22A Simple Example of the SDO_NN Operatorlisting-08-22.sql
8-23SDO_NN Operator Retrieving the Five Nearest Customers to a Specific Competitorlisting-08-23.sql
8-24SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitorlisting-08-24.sql
8-25SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Competitorlisting-08-25.sql
8-26SDO_NN Operator Retrieving the Five Customers Nearest to a Specific Competitorlisting-08-26.sql
8-27SDO_NN Operator Retrieving the Five Customers Nearest to a Specific Competitor Along with Their Distanceslisting-08-27.sql
8-28SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitor Along with Their Distanceslisting-08-28.sql
8-29Rewriting Listing 8-27 with Mile As the Distance Unitlisting-08-29.sql
8-30Rewriting Listing 8-28 with Mile As the Distance Unitlisting-08-30.sql
8-31Creating the Sales Region (Area of Influence) for Each Competitor/Branchlisting-08-31.sql
8-32Creating Indexes on Sales Regions of Competitors/Brancheslisting-08-32.sql
8-33SDO_FILTER Operator Retrieving All Customers Within a Competitor's Service Arealisting-08-33.sql
8-34Typical Query from MapViewer Using the SDO_FILTER Operatorlisting-08-34.sql
8-35SDO_RELATE Operator Retrieving All Customers in a Quarter-Mile Buffer Zone of a Competitor Storelisting-08-35.sql
8-36Identifying a DISJOINT relationshiplisting-08-36.sql
8-37SDO_RELATE Operator Identifying All Competitors in the D.C. Regionlisting-08-37.sql
8-38SDO_RELATE Operator Identifying All Competitors Inside the D.C. Regionlisting-08-38.sql
8-39SDO_RELATE Operator Identifying All Competitors That Overlap the D.C. Regionlisting-08-39.sql
8-40Identifying Sales Regions That Intersect a Specific Sales Region (id=51)listing-08-40.sql
8-41Identifying All Sales Regions That Overlap a Specific Sales Region (id=51)listing-08-41.sql
8-42Verifying That a Sales Region Touches Another Sales Region (id=51)listing-08-42.sql
8-43Adding the SDO_LEVEL=6 Parameter to an SDO_RELATE Querylisting-08-43.sql
8-44Explaining the Execution Plan for a SQL Statementlisting-08-44.sql
8-45SDO_NN Operator Retrieving the Five GOLD Customers Nearest to a Specific Competitor Along with Their Distanceslisting-08-45.sql
8-46Creating an Index on customer_grade and Rerunning Listing 8-45listing-08-46.sql
8-47Usage of Hints with SDO_NN and Other Operators on the Same Tablelisting-08-47.sql
8-48Spatial Operator with Multiple Hints in a SQL Statement with Two Tableslisting-08-48.sql
8-49Creating a Deterministic Function to Return an SDO_GEOMETRYUsing Address Attributes of the customers Tablelisting-08-49.sql
8-50Declaring the gcdr_geometry Function As DETERMINISTIClisting-08-50.sql
8-51Inserting the Metadata for a listing-08-51.sql
8-52Creating a Spatial Index on a Function Returning an SDO_GEOMETRYlisting-08-52.sql
8-53Setting Session Parameters to Enable Query Rewrite on Function-Based Indexeslisting-08-53.sql
8-54SDO_NN Operator Retrieving the Five Customers Nearest to Each Competitor Using the Function-Based Indexlisting-08-54.sql
8-55Creating a Partitioned Tablelisting-08-55.sql
8-57Creating a Local Partitioned Spatial Index with Partition-Specific Parameterslisting-08-57.sql
8-58SDO_WITHIN_DISTANCE Operator on a Partitioned Tablelisting-08-58.sql
8-59Obtaining the Five Customers Nearest to Each Competitor When the customers Table Has a Local Partitioned Indexlisting-08-59.sql
8-61Setting the Degree of Parallelism to 2 for a Tablelisting-08-61.sql
8-62SDO_RELATE Operator Retrieving All Customers Inside (and Touching the Border of) Each Competitor Regionlisting-08-62.sql
8-63SDO_JOIN Operator Analyzing the Number of Customers Inside All the Competitor Regionslisting-08-63.sql
8-64SDO_FILTER Operator Retrieving All Customers Whose MBRs Intersect Those of Competitor Regionslisting-08-64.sql
8-65SDO_JOIN Operator Retrieving All Customers Whose MBRs Intersect the MBRs of Competitor Regions (Filter Operation Is Used)listing-08-65.sql
+ +

Chapter 9 - Spatial Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
9-1Creating Buffers Around Brancheslisting-09-01.sql
9-2Creating Buffers Around Competitor Locationslisting-09-02.sql
9-3Identifying Customers Within a Quarter-Mile of a Competitor Locationlisting-09-03.sql
9-4Using the SDO_DISTANCE Function with the SDO_WITHIN_DISTANCE Spatial Operator in SQLlisting-09-04.sql
9-5Identifying Customers Inside a Competitor's Sales Regionlisting-09-05.sql
9-6Identifying Customers That Interact with a Competitor's Sales Regionlisting-09-06.sql
9-7Identifying Suppliers in a Quarter-Mile Buffer Around a Competitorlisting-09-07.sql
9-8Identifying Customers in Quarter-Mile Buffer Around a Competitorlisting-09-08.sql
9-9RELATE Function Complementing the SDO_RELATE Operatorlisting-09-09.sql
9-10SDO_INTERSECTION of Two Geometrieslisting-09-10.sql
9-11Sales Regions Intersecting the Sales Region with id=51listing-09-11.sql
9-12Identifying Customers in sales_ intersection_zoneslisting-09-12.sql
9-13Identifying Customers in the Intersection of Sales Regions 51 and 43listing-09-13.sql
9-14SDO_UNION of Two Geometrieslisting-09-14.sql
9-15Coverage of the Sales Regions Performing a Union of All the Sales Regionslisting-09-15.sql
9-16SDO_DIFFERENCE of Competitor Region 2 with Sales Region 6listing-09-16.sql
9-17Identifying Customers in an Exclusive Zone of a Competitorlisting-09-17.sql
9-18Combining Listings 9-16 and 9-17listing-09-18.sql
9-19SDO_XOR of Sales Regions 43 and 51 to Identify Customers That Are Not Shared Between Themlisting-09-19.sql
9-20Area of the Intersection Region of Sales Region 43 and Sales Region 51listing-09-20.sql
9-21Identifying Interstates Shorter Than 1 Milelisting-09-21.sql
9-22Computing the MBR of a Geometrylisting-09-22.sql
9-23Obtaining the MIN_ORDINATEs and MAX_ORDINATEs in a Specific Dimensionlisting-09-23.sql
9-24Computing the Convex Hull for the State of New Hampshirelisting-09-24.sql
9-25Computing the Centroid for the State of New Hampshirelisting-09-25.sql
9-26Obtaining a Point on the Surface of the Geometry of the State of Massachusettslisting-09-26.sql
9-27Finding the Extent of a Set of Geometries Using SDO_AGGR_MBRlisting-09-27.sql
9-28Finding the Coverage of Branches Using SDO_AGGR_UNIONlisting-09-28.sql
9-29Union of Three Sales Regions (ids 43, 51, and 2)listing-09-29.sql
9-30Union of All Sales Regions to Obtain Business Coveragelisting-09-30.sql
9-31Finding the Coverage of sales_regions Using SDO_AGGR_CONVEXHULLlisting-09-31.sql
9-32Finding the Centroid of Customer Locations Using SDO_AGGR_CENTROIDlisting-09-32.sql
+ +

Chapter 10 - Network Modelling and Tracing

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
10-1Creating a Spatial Network Using Default Table Nameslisting-10-01.sql
10-2Structure of Default Network Tableslisting-10-02.sql
10-3Network Creation with Explicit Table and Column Nameslisting-10-03.sql
10-4Manual Network Creationlisting-10-04.sql
10-5Setting Up Network Metadatalisting-10-05.sql
10-6Setting Up Metadata for a Time-Based Road Networklisting-10-06.sql
10-7Existing Water Network Tableslisting-10-07.sql
10-8Views over Existing Tableslisting-10-08.sql
10-9Creating the Path and Path Link Tableslisting-10-09.sql
10-10Metadata for a Network on Existing Structureslisting-10-10.sql
10-11Validating a Network Definitionlisting-10-11.sql
10-12Dropping a Networklisting-10-12.sql
10-13Adding Spatial Metadata to Network Tableslisting-10-13.sql
10-14Convenient Procedure for Getting Network Detailslisting-10-14.sql
10-15Getting Network Detailslisting-10-15.sql
10-16Defining the UNET Networklisting-10-16.sql
10-17Loading the UNET Networklisting-10-17.sql
10-18Defining the DNET Networklisting-10-18.sql
10-19Loading the DNET Networklisting-10-19.sql
10-20Using the shortestPath()Methodlisting-10-20.java
10-21Using the nearestNeighbors()Methodlisting-10-21.java
10-22Using the withinCost()Methodlisting-10-22.java
10-23Using the tspPath()Methodlisting-10-23.java
10-24Using the findReachableNodes()Methodlisting-10-24.java
10-25Using the mcst()Methodlisting-10-25.java
10-26Using the allPaths()Methodlisting-10-26.java
10-27Using the shortestPaths()Methodlisting-10-27.java
10-28Using the SystemConstraint Classlisting-10-28.java
10-29Setting Link Levels for the UNET Networklisting-10-29.sql
10-30Network Constraintlisting-10-30.java
10-31Using the Network Constraintlisting-10-31.java
10-32Creating a Network Using the Java APIlisting-10-32.java
10-33Starting the Network Editorlisting-10-33.bat
+ +

Chapter 11 - Generating Maps

+ + + + + + + + + + + + + +
ListingDescriptionFile Name
11-1Branches in San Franciscolisting-11-01.sql
11-2Loading Maps, Themes, and Style Definitionslisting-11-02.sql
11-3Define a Data Sourcelisting-11-03.xml
11-4Setting the log levellisting-11-04.xml
11-5Controling map image lifetimelisting-11-05.xml
11-6Controlling the data cachelisting-11-06.xml
11-7Defining a permanent data sourcelisting-11-07.xml
11-8Defining a permanent OC4J data sourcelisting-11-08.xml
11-9Setting Global Map Optionslisting-11-09.xml
11-10Starting the Map definition toollisting-11-10.bat
N/ACode Examples and applicationsweb-examples.zip
+ +

Chapter 12 - Putting it together: an example application

+ + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
12-1Loading the Geographical Datalisting-12-01.sql
12-2Loading and Location-Enabling the Business Datalisting-12-02.sql
12-3Loading Map Definitionslisting-12-03.sql
12-4Functions to Extract x and y Coordinateslisting-12-04.sql
12-5Reset Actionlisting-12-05.java
12-6Zoom Actionslisting-12-06.java
12-7Pan Actionslisting-12-07.java
12-8reCenter Actionlisting-12-08.java
12-9updateMap Actionlisting-12-09.java
12-10Find Actionlisting-12-10.java
12-11identify Actionlisting-12-11.java
12-12setMark Actionlisting-12-12.java
12-13distSearch Actionlisting-12-13.java
12-14nnSearch Actionlisting-12-14.java
12-15Calculating a Routelisting-12-15.java
12-16Example Applicationlisting-12-16.jsp
+ +

Chapter 13 - Case Studies

+ +

Chapter 14 - Tips and common mistakes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
14-1Correcting the Orientation of a Polygon Geometry Using TO_CURRENTlisting-14-01.sql
14-2Correcting a Self-Crossing Polygon Geometry Using SDO_UNIONlisting-14-02.sql
14-3Nearest-Neighbor Query on the customers Tablelisting-14-03.sql
14-4Specifying LAYER_GTYPE During Spatial Index Creationlisting-14-04.sql
14-5Creating an Empty Table with the Same Structure As the us_streets Tablelisting-14-05.sql
14-6Reinserting into the us_streets Table Based on the linear_key Orderlisting-14-06.sql
14-7Using the linear_key Function to Order Geometry Rows Based on a 'Spatial' Orderinglisting-14-07.sql
14-8Aggregate Union of All Geometries in the us_counties Tablelisting-14-08.sql
14-9Computing the Aggregate Unions for Multiple Groupslisting-14-09.sql
14-10Computing the Aggregate Unions Grouped by the ROWNUM Pseudo Columnlisting-14-10.sql
14-11Computing the Aggregate Union of Aggregate Unions Grouped by the ROWNUM Pseudo-Columnlisting-14-11.sql
14-12Computing the Aggregate Union in a Pipelined Fashionlisting-14-12.sql
14-13Setting the SDO_DML_BATCH_SIZE Parameterlisting-14-13.sql
14-14Creating a Partitioned Table for Storing Temporal Weather Pattern Datalisting-14-14.sql
14-15Creating a Local Partitioned Spatial Indexlisting-14-15.sql
14-16Creating a Local Partitioned Spatial Index As 'Unusable'listing-14-16.sql
14-17Rebuilding a Local Spatial Indexlisting-14-17.sql
14-18Rebuilding All UNUSABLE Indexes for a Table Partitionlisting-14-18.sql
14-19Exchanging tmp Data with Partition p1 of weather_patternsWithout Indexeslisting-14-19.sql
14-20Adding New Data Using the EXCHANGE PARTITION Clauselisting-14-20.sql
14-21Splitting the current_month Partition into march and current_month Partitionslisting-14-21.sql
14-22Rebuilding the Indexes for the 'Split' Partitionslisting-14-22.sql
14-23Merging the Partitions for jan and feb into a Single Partitionlisting-14-23.sql
14-24Renaming a Partitionlisting-14-24.sql
14-25Renaming the Merged Monthly Partition As a Year Partitionlisting-14-25.sql
14-26Setting the location Column in the customers Table to a NULLValuelisting-14-26.sql
14-27Determining the SRIDValue in the Location (Geometry) Columns of a Tablelisting-14-27.sql
14-28Determining the SRIDValue for a Spatial Layer (Specified by table_name, column_name)listing-14-28.sql
+ +

Appendix A - Advanced Spatial Analysis

+ + + + + + + + + +
ListingDescriptionFile Name
A-1Tiling a Two-Dimensional Spacelisting-A-01.sql
A-2Zip Code Table Used to Get Demographic Informationlisting-A-02.sql
A-3Searching for Regions (Tiles) That Have a Population Greater Than 30,000listing-A-03.sql
A-4Estimating the Population in Sales Region 1 Using the Demographic Information in the zip5_dc Tablelisting-A-04.sql
A-5Estimating the Population for All Rows in the sales_regions Table Using Demographic Information in the zip5_dc Tablelisting-A-05.sql
A-6Finding Three Clusters for Customer Locationslisting-A-06.sql
A-7Simplifying the Geometry for New Hampshirelisting-A-07.sql
+ +

Appendix B - Linear Referencing

+ +

Appendix C - Topology Data Model

+ +

Appendix D - GeoRaster

+ + + + + + + + + + + + + + + + + +
ListingDescriptionFile Name
D-1Altering the branches Table to Add the georaster Columnlisting-D-01.sql
D-2Structure of SDO_GEORASTERlisting-D-02.sql
D-3Creating the Raster Data Tablelisting-D-03.sql
D-4Creating a Trigger to Populate the Raster Data Tablelisting-D-04.sql
D-5Initializing the georaster Column in the branches Tablelisting-D-05.sql
D-6Populating the Georaster Column with a TIFF Imagelisting-D-06.sql
D-7Granting Permissions to Import Data into a GeoRaster Columnlisting-D-07.sql
D-8Generating Pyramids for a GeoRaster Object in the branches Tablelisting-D-08.sql
D-9Subsetting a GeoRaster Objectlisting-D-09.sql
D-10Georeferencing a GeoRaster Objectlisting-D-10.sql
D-11Generating and Populating the Spatial Extent of the georaster Columnlisting-D-11.sql
D-12Populating the Metadata for the Spatial Extent of the georaster Columnlisting-D-12.sql
D-13Creating an Index on the Spatial Extent of the georaster Columnlisting-D-13.sql
D-14Creating a Predefined Theme for the georaster Column in the branches Tablelisting-D-14.sql
D-15Creating a Dynamic Theme for GeoRaster Objectslisting-D-15.xml
+ + + diff --git a/ProOracleSpatialCode/cover.jpg b/ProOracleSpatialCode/cover.jpg new file mode 100644 index 0000000..87ea336 Binary files /dev/null and b/ProOracleSpatialCode/cover.jpg differ diff --git a/ProOracleSpatialCode/data.html b/ProOracleSpatialCode/data.html new file mode 100644 index 0000000..991167a --- /dev/null +++ b/ProOracleSpatialCode/data.html @@ -0,0 +1,161 @@ + + + + + Essential Guide To Oracle Spatial - Data + + +

Pro Oracle Spatial - Data Files
+

+You will have to download the ProOracleSpatialData.zip separately from +the Apress website. This zip file contains the following data files.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data CategoryContentFile Name
Large scale map dataContinents and countries, US states, counties, interstates, +rivers and parksmap_large.dmp
City level dataStreet-level information for San Francisco and Washington, DCmap_detailed.dmp
Application Databranches, customers, competitors tablesapp_data.dmp
Application DataSame, but spatially enabledapp_with_loc.dmp
GeocodingGeocoding data set for San Francisco and Washington, DCgc.dmp
NetworkingStreet network for San Francisconet.dmp
Maps and stylesMap definitions, themes and stylesstyles.dmp
DemographicsZip codes in Washington DC with populationzip.dmp
+

Loading instructions

+The above data files can be loaded into an Oracle database using the +following loading scripts.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ChapterLoading instructionsFile Name
Chapter 2
+
chapter-02-import.bat
Chapter 3
+
chapter-03-import.bat
Chapter 4
+
chapter-04-import.bat
Chapter 5
+
chapter-05-import.bat
Chapter 6
+
chapter-06-import.bat
Chapter 7
+
chapter-07-import.bat
Chapter 8
+
chapter-08-import.bat
Chapter 9
+
chapter-09-import.bat
Chapter 10
+
chapter-10-import.bat
Chapter 11
+
chapter-11-import.bat
Chapter 12
+
chapter-12-import.bat
Appendix A
+
appendix-a-import.bat
+ + diff --git a/ProOracleSpatialCode/frontcover.gif b/ProOracleSpatialCode/frontcover.gif new file mode 100644 index 0000000..519678f Binary files /dev/null and b/ProOracleSpatialCode/frontcover.gif differ diff --git a/ProOracleSpatialCode/readme.html b/ProOracleSpatialCode/readme.html new file mode 100644 index 0000000..cd7418a --- /dev/null +++ b/ProOracleSpatialCode/readme.html @@ -0,0 +1,165 @@ + + + + + Pro Oracle Spatial + + + + + + + + + +
+ + + + + + + +
Front Cover
+

+
+

Pro +Oracle Spatial

+
+

The +Essential Guide

+
+

to +developing spatially-enabled applications

+

 Ravi Kothuri, Albert +Godfrind, +and Euro Beinat

+
+
+
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table of +Contents
+
About +theAuthors
+
Errata
+
Software +to Install
+
Data for +Examples
+
Code Examples
+
Feedback +to Authors
+
Order
+
+

+
Thank you for purchasing Pro Oracle Spatial. +This book is an +essential guide to developing spatially-enabled applications using +Oracle Spatial technology.  With +Oracle Spatial, you can store, retrieve, analyze and visualize spatial +data +just like any other type of data, and integrate it in any business +application running on an Oracle platform. This book will +familiarize you with spatial information +management inside Oracle and provides the conceptual knowledge and +requisite practical +skills to turn a novice reader into a professional spatial developer. +Additionally, the book will illustrate +how to integrate spatial technology  in applications and how organizations have +been successfully implementing it. The book comes with sample data, code examples and tips, +so that +you can learn, experiment and find guidance in becoming an expert in +Oracle +Spatial. You may need to install specific +Oracle software to try these +examples.
+
+ Pro Oracle Spatial  + is the first and only book on Oracle Spatial technology. +We hope +that by reading this book you will be able to add +a new and important set of skills to your background. This book is +especially +packaged to suit Oracle application developers who can leverage the +functionality of Oracle Spatial immediately and add value to their +applications. This book  will allow you +to develop exciting applications, be part of large and inspiring +projects, and +exploit the rich world of spatial +data and location analysis. It is our hope that +you will find this world as interesting and challenging as we do. +
+
+
+ + diff --git a/ProOracleSpatialCode/software.html b/ProOracleSpatialCode/software.html new file mode 100644 index 0000000..fb41886 --- /dev/null +++ b/ProOracleSpatialCode/software.html @@ -0,0 +1,33 @@ + + + + + Pro Oracle Spatial - Software + + + +

Pro Oracle Spatial - Software

+

You may have to install the following software components to run +the examples in the book.
+The following URLs take you to the
Oracle +Technology Network's download site.  You need to pick up the +software for the following two components on this page.
+

+
    +
  • +

    Oracle Application Server Containers for J2EE (OC4J) Standalone
    +

    +
  • +
+
    +
  • +

    Oracle Application Server Mapviewer

    +
  • +
+Note that you will need to register to download this software.
+
+
+ + diff --git a/ProOracleSpatialCode/toc.shtml b/ProOracleSpatialCode/toc.shtml new file mode 100644 index 0000000..52ccf55 --- /dev/null +++ b/ProOracleSpatialCode/toc.shtml @@ -0,0 +1,33 @@ + + + + + +

Table of Contents
+

+
+
CHAPTER 1      Spatial +InformationManagement
+CHAPTER 2      Overview of Oracle Spatial
+CHAPTER 3      Location-Enabling Your +Applications
+CHAPTER 4      The SDO_GEOMETRY Data Type
+CHAPTER 5      Loading, Transporting, and +Validating Spatial Data
+CHAPTER 6      Geocoding
+CHAPTER 7      Manipulating SDO_GEOMETRY in +Application Programs
+CHAPTER 8      Spatial Indexes and Operators
+CHAPTER 9      Geometry ProcessingFunctions
+CHAPTER 10    Network Modeling
+CHAPTER 11    Generating Maps Using MapViewer
+CHAPTER 12    A Sample Application
+CHAPTER 13    Case Studies
+CHAPTER 14    Tips, Common Mistakes, and Common Errors
+APPENDIX A   Spatial AnalysisFunctions
+APPENDIX B   Linear Referencing
+APPENDIX C   Topology Data Model in Oracle
+APPENDIX D   Storing Raster Data in Oracle
+
+ + diff --git a/ProOracleSpatialData/Data/app_data.dmp b/ProOracleSpatialData/Data/app_data.dmp new file mode 100644 index 0000000..eb05578 Binary files /dev/null and b/ProOracleSpatialData/Data/app_data.dmp differ diff --git a/ProOracleSpatialData/Data/app_with_loc.dmp b/ProOracleSpatialData/Data/app_with_loc.dmp new file mode 100644 index 0000000..1c8a09d Binary files /dev/null and b/ProOracleSpatialData/Data/app_with_loc.dmp differ diff --git a/ProOracleSpatialData/Data/gc.dmp b/ProOracleSpatialData/Data/gc.dmp new file mode 100644 index 0000000..b34c967 Binary files /dev/null and b/ProOracleSpatialData/Data/gc.dmp differ diff --git a/ProOracleSpatialData/Data/map_detailed.dmp b/ProOracleSpatialData/Data/map_detailed.dmp new file mode 100644 index 0000000..0cd3d89 Binary files /dev/null and b/ProOracleSpatialData/Data/map_detailed.dmp differ diff --git a/ProOracleSpatialData/Data/map_large.dmp b/ProOracleSpatialData/Data/map_large.dmp new file mode 100644 index 0000000..ff283d5 Binary files /dev/null and b/ProOracleSpatialData/Data/map_large.dmp differ diff --git a/ProOracleSpatialData/Data/net.dmp b/ProOracleSpatialData/Data/net.dmp new file mode 100644 index 0000000..45ba6a7 Binary files /dev/null and b/ProOracleSpatialData/Data/net.dmp differ diff --git a/ProOracleSpatialData/Data/styles.dmp b/ProOracleSpatialData/Data/styles.dmp new file mode 100644 index 0000000..9da1ba3 Binary files /dev/null and b/ProOracleSpatialData/Data/styles.dmp differ diff --git a/ProOracleSpatialData/Data/zip.dmp b/ProOracleSpatialData/Data/zip.dmp new file mode 100644 index 0000000..94cfc0d Binary files /dev/null and b/ProOracleSpatialData/Data/zip.dmp differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e264c7a --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Pro Oracle Spatial*](http://www.apress.com/9781590593837) by Ravikanth Kothuri, Euro Beinat, and Albert Godfrind (Apress, 2004). + +![Cover image](9781590593837.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file