From 10fda595013fcc7210155facfd09fcff2c7b9238 Mon Sep 17 00:00:00 2001 From: Apress Date: Thu, 6 Oct 2016 01:58:01 +0100 Subject: [PATCH] First commit --- 1911.pdf | Bin 0 -> 422603 bytes 1930.html | 25 + 2443.html | 1 + 9781590593837.jpg | Bin 0 -> 10586 bytes LICENSE.txt | 27 + .../Code/Appendix-A/listing-A-01.sql | 3 + .../Code/Appendix-A/listing-A-02.sql | 2 + .../Code/Appendix-A/listing-A-03.sql | 8 + .../Code/Appendix-A/listing-A-04.sql | 4 + .../Code/Appendix-A/listing-A-05.sql | 9 + .../Code/Appendix-A/listing-A-06.sql | 3 + .../Code/Appendix-A/listing-A-07.sql | 4 + .../Code/Appendix-D/listing-D-01.sql | 2 + .../Code/Appendix-D/listing-D-02.sql | 2 + .../Code/Appendix-D/listing-D-03.sql | 10 + .../Code/Appendix-D/listing-D-04.sql | 2 + .../Code/Appendix-D/listing-D-05.sql | 4 + .../Code/Appendix-D/listing-D-06.sql | 16 + .../Code/Appendix-D/listing-D-07.sql | 18 + .../Code/Appendix-D/listing-D-08.sql | 10 + .../Code/Appendix-D/listing-D-09.sql | 17 + .../Code/Appendix-D/listing-D-10.sql | 17 + .../Code/Appendix-D/listing-D-11.sql | 10 + .../Code/Appendix-D/listing-D-12.sql | 14 + .../Code/Appendix-D/listing-D-13.sql | 3 + .../Code/Appendix-D/listing-D-14.sql | 13 + .../Code/Appendix-D/listing-D-15.xml | 11 + .../Code/Chapter-02/listing-02-01.sql | 7 + .../Code/Chapter-02/listing-02-02.sql | 20 + .../Code/Chapter-02/listing-02-03.sql | 13 + .../Code/Chapter-02/listing-02-04.sql | 11 + .../Code/Chapter-02/listing-02-05.sql | 4 + .../Code/Chapter-02/listing-02-06.sql | 6 + .../Code/Chapter-02/listing-02-07.sql | 10 + .../Code/Chapter-02/listing-02-08.sql | 4 + .../Code/Chapter-03/listing-03-01.sql | 15 + .../Code/Chapter-03/listing-03-02.sql | 16 + .../Code/Chapter-03/listing-03-03.sql | 2 + .../Code/Chapter-03/listing-03-04.sql | 4 + .../Code/Chapter-03/listing-03-05.sql | 14 + .../Code/Chapter-03/listing-03-06.sql | 4 + .../Code/Chapter-03/listing-03-07.sql | 13 + .../Code/Chapter-03/listing-03-08.sql | 13 + .../Code/Chapter-03/listing-03-09.sql | 12 + .../Code/Chapter-03/listing-03-10.sql | 15 + .../Code/Chapter-03/listing-03-11.sql | 2 + .../Code/Chapter-03/listing-03-12.sql | 4 + .../Code/Chapter-03/listing-03-13.sql | 4 + .../Code/Chapter-03/listing-03-14.sql | 2 + .../Code/Chapter-03/listing-03-15.sql | 26 + .../Code/Chapter-04/listing-04-01.sql | 7 + .../Code/Chapter-04/listing-04-02.sql | 2 + .../Code/Chapter-04/listing-04-03.sql | 4 + .../Code/Chapter-04/listing-04-04.sql | 4 + .../Code/Chapter-04/listing-04-05.sql | 4 + .../Code/Chapter-04/listing-04-06.sql | 4 + .../Code/Chapter-04/listing-04-07.sql | 2 + .../Code/Chapter-04/listing-04-08.sql | 7 + .../Code/Chapter-04/listing-04-09.sql | 2 + .../Code/Chapter-04/listing-04-10.sql | 20 + .../Code/Chapter-04/listing-04-11.sql | 2 + .../Code/Chapter-04/listing-04-12.sql | 24 + .../Code/Chapter-04/listing-04-13.sql | 17 + .../Code/Chapter-04/listing-04-14.sql | 25 + .../Code/Chapter-04/listing-04-15.sql | 25 + .../Code/Chapter-04/listing-04-16.sql | 27 + .../Code/Chapter-04/listing-04-17.sql | 24 + .../Code/Chapter-04/listing-04-18.sql | 25 + .../Code/Chapter-05/listing-05-01.sql | 6 + .../Code/Chapter-05/listing-05-02.sql | 24 + .../Code/Chapter-05/listing-05-03.ctl | 22 + .../Code/Chapter-05/listing-05-04.bat | 2 + .../Code/Chapter-05/listing-05-05.bat | 2 + .../Code/Chapter-05/listing-05-06.ctl | 19 + .../Code/Chapter-05/listing-05-07.dat | 2 + .../Code/Chapter-05/listing-05-08.ctl | 27 + .../Code/Chapter-05/listing-05-09.bat | 2 + .../Code/Chapter-05/listing-05-10.bat | 2 + .../Code/Chapter-05/listing-05-11.bat | 2 + .../Code/Chapter-05/listing-05-12.bat | 8 + .../Code/Chapter-05/listing-05-13.bat | 2 + .../Code/Chapter-05/listing-05-14.bat | 5 + .../Code/Chapter-05/listing-05-15.sql | 2 + .../Code/Chapter-05/listing-05-16.sql | 2 + .../Code/Chapter-05/listing-05-17.bat | 2 + .../Code/Chapter-05/listing-05-18.sql | 26 + .../Code/Chapter-05/listing-05-19.bat | 3 + .../Code/Chapter-05/listing-05-20.sql | 4 + .../Code/Chapter-05/listing-05-21.sql | 4 + .../Code/Chapter-05/listing-05-22.sql | 9 + .../Code/Chapter-05/listing-05-24.sql | 4 + .../Code/Chapter-05/listing-05-25.sql | 26 + .../Code/Chapter-05/listing-05-26.sql | 18 + .../Code/Chapter-05/listing-05-28.sql | 12 + .../Code/Chapter-05/listing-05-29.sql | 4 + .../Code/Chapter-05/listing-05-30.sql | 8 + .../Code/Chapter-05/listing-05-31.sql | 24 + .../Code/Chapter-05/listing-05-32.sql | 20 + .../Code/Chapter-05/listing-05-33.sql | 20 + .../Code/Chapter-05/listing-05-34.sql | 20 + .../Code/Chapter-05/listing-05-35.sql | 31 + .../Code/Chapter-05/listing-05-36.sql | 4 + .../Code/Chapter-06/listing-06-01.sql | 12 + .../Code/Chapter-06/listing-06-02.sql | 13 + .../Code/Chapter-06/listing-06-03.sql | 8 + .../Code/Chapter-06/listing-06-04.sql | 8 + .../Code/Chapter-06/listing-06-05.sql | 8 + .../Code/Chapter-06/listing-06-06.sql | 9 + .../Code/Chapter-06/listing-06-07.sql | 65 + .../Code/Chapter-06/listing-06-08.sql | 13 + .../Code/Chapter-06/listing-06-09.sql | 6 + .../Code/Chapter-06/listing-06-10.sql | 13 + .../Code/Chapter-06/listing-06-11.sql | 13 + .../Code/Chapter-06/listing-06-12.sql | 13 + .../Code/Chapter-06/listing-06-13.sql | 13 + .../Code/Chapter-06/listing-06-14.sql | 13 + .../Code/Chapter-06/listing-06-15.sql | 16 + .../Code/Chapter-06/listing-06-16.sql | 13 + .../Code/Chapter-06/listing-06-17.sql | 13 + .../Code/Chapter-06/listing-06-18.sql | 4 + .../Code/Chapter-06/listing-06-19.sql | 11 + .../Code/Chapter-06/listing-06-20.sql | 10 + .../Code/Chapter-06/listing-06-21.sql | 122 ++ .../Code/Chapter-06/listing-06-22.sql | 18 + .../Code/Chapter-06/listing-06-23.sql | 57 + .../Code/Chapter-07/SdoLoad.java | 188 +++ .../Code/Chapter-07/SdoPrint.java | 298 +++++ .../Code/Chapter-07/listing-07-01.sql | 6 + .../Code/Chapter-07/listing-07-02.sql | 6 + .../Code/Chapter-07/listing-07-03.sql | 68 + .../Code/Chapter-07/listing-07-04.sql | 87 ++ .../Code/Chapter-07/listing-07-05.sql | 11 + .../Code/Chapter-07/listing-07-06.sql | 17 + .../Code/Chapter-07/listing-07-07.sql | 17 + .../Code/Chapter-07/listing-07-08.sql | 9 + .../Code/Chapter-07/listing-07-09.sql | 37 + .../Code/Chapter-07/listing-07-10.sql | 16 + .../Code/Chapter-07/listing-07-11.sql | 42 + .../Code/Chapter-07/listing-07-12.sql | 55 + .../Code/Chapter-07/listing-07-13.java | 298 +++++ .../Code/Chapter-07/listing-07-14.bat | 2 + .../Code/Chapter-07/listing-07-15.java | 188 +++ .../Code/Chapter-07/load_geom.c | 452 +++++++ .../Code/Chapter-07/oci_sample.c | 389 ++++++ .../Code/Chapter-07/oci_sample_array.c | 426 +++++++ .../Code/Chapter-07/preadgeom.pc | 186 +++ .../Code/Chapter-07/pwritegeom.pc | 308 +++++ .../Code/Chapter-07/read_geom.c | 974 +++++++++++++++ .../Code/Chapter-07/read_geom_array.c | 705 +++++++++++ .../Code/Chapter-07/read_points.c | 327 +++++ .../Code/Chapter-07/read_points_array.c | 371 ++++++ .../Code/Chapter-07/select_pois.c | 474 +++++++ .../Code/Chapter-08/listing-08-01.sql | 6 + .../Code/Chapter-08/listing-08-02.sql | 3 + .../Code/Chapter-08/listing-08-03.sql | 2 + .../Code/Chapter-08/listing-08-04.sql | 26 + .../Code/Chapter-08/listing-08-05.sql | 2 + .../Code/Chapter-08/listing-08-06.sql | 3 + .../Code/Chapter-08/listing-08-07.sql | 3 + .../Code/Chapter-08/listing-08-09.sql | 4 + .../Code/Chapter-08/listing-08-10.sql | 4 + .../Code/Chapter-08/listing-08-11.sql | 4 + .../Code/Chapter-08/listing-08-12.sql | 4 + .../Code/Chapter-08/listing-08-13.sql | 4 + .../Code/Chapter-08/listing-08-14.sql | 4 + .../Code/Chapter-08/listing-08-15.sql | 4 + .../Code/Chapter-08/listing-08-16.sql | 4 + .../Code/Chapter-08/listing-08-17.sql | 8 + .../Code/Chapter-08/listing-08-19.sql | 6 + .../Code/Chapter-08/listing-08-20.sql | 7 + .../Code/Chapter-08/listing-08-21.sql | 9 + .../Code/Chapter-08/listing-08-22.sql | 5 + .../Code/Chapter-08/listing-08-23.sql | 7 + .../Code/Chapter-08/listing-08-24.sql | 8 + .../Code/Chapter-08/listing-08-25.sql | 8 + .../Code/Chapter-08/listing-08-26.sql | 5 + .../Code/Chapter-08/listing-08-27.sql | 7 + .../Code/Chapter-08/listing-08-28.sql | 8 + .../Code/Chapter-08/listing-08-29.sql | 7 + .../Code/Chapter-08/listing-08-30.sql | 10 + .../Code/Chapter-08/listing-08-31.sql | 9 + .../Code/Chapter-08/listing-08-32.sql | 20 + .../Code/Chapter-08/listing-08-33.sql | 6 + .../Code/Chapter-08/listing-08-34.sql | 13 + .../Code/Chapter-08/listing-08-35.sql | 6 + .../Code/Chapter-08/listing-08-36.sql | 10 + .../Code/Chapter-08/listing-08-37.sql | 5 + .../Code/Chapter-08/listing-08-38.sql | 5 + .../Code/Chapter-08/listing-08-39.sql | 5 + .../Code/Chapter-08/listing-08-40.sql | 6 + .../Code/Chapter-08/listing-08-41.sql | 7 + .../Code/Chapter-08/listing-08-42.sql | 6 + .../Code/Chapter-08/listing-08-43.sql | 5 + .../Code/Chapter-08/listing-08-44.sql | 11 + .../Code/Chapter-08/listing-08-45.sql | 9 + .../Code/Chapter-08/listing-08-46.sql | 13 + .../Code/Chapter-08/listing-08-47.sql | 9 + .../Code/Chapter-08/listing-08-48.sql | 7 + .../Code/Chapter-08/listing-08-49.sql | 18 + .../Code/Chapter-08/listing-08-50.sql | 4 + .../Code/Chapter-08/listing-08-51.sql | 12 + .../Code/Chapter-08/listing-08-52.sql | 7 + .../Code/Chapter-08/listing-08-53.sql | 3 + .../Code/Chapter-08/listing-08-54.sql | 12 + .../Code/Chapter-08/listing-08-55.sql | 19 + .../Code/Chapter-08/listing-08-57.sql | 10 + .../Code/Chapter-08/listing-08-58.sql | 8 + .../Code/Chapter-08/listing-08-59.sql | 10 + .../Code/Chapter-08/listing-08-61.sql | 2 + .../Code/Chapter-08/listing-08-62.sql | 5 + .../Code/Chapter-08/listing-08-63.sql | 14 + .../Code/Chapter-08/listing-08-64.sql | 4 + .../Code/Chapter-08/listing-08-65.sql | 13 + .../Code/Chapter-09/listing-09-01.sql | 5 + .../Code/Chapter-09/listing-09-02.sql | 5 + .../Code/Chapter-09/listing-09-03.sql | 6 + .../Code/Chapter-09/listing-09-04.sql | 8 + .../Code/Chapter-09/listing-09-05.sql | 6 + .../Code/Chapter-09/listing-09-06.sql | 6 + .../Code/Chapter-09/listing-09-07.sql | 5 + .../Code/Chapter-09/listing-09-08.sql | 7 + .../Code/Chapter-09/listing-09-09.sql | 13 + .../Code/Chapter-09/listing-09-10.sql | 7 + .../Code/Chapter-09/listing-09-11.sql | 4 + .../Code/Chapter-09/listing-09-12.sql | 5 + .../Code/Chapter-09/listing-09-13.sql | 13 + .../Code/Chapter-09/listing-09-14.sql | 9 + .../Code/Chapter-09/listing-09-15.sql | 12 + .../Code/Chapter-09/listing-09-16.sql | 6 + .../Code/Chapter-09/listing-09-17.sql | 5 + .../Code/Chapter-09/listing-09-18.sql | 12 + .../Code/Chapter-09/listing-09-19.sql | 9 + .../Code/Chapter-09/listing-09-20.sql | 6 + .../Code/Chapter-09/listing-09-21.sql | 4 + .../Code/Chapter-09/listing-09-22.sql | 4 + .../Code/Chapter-09/listing-09-23.sql | 5 + .../Code/Chapter-09/listing-09-24.sql | 4 + .../Code/Chapter-09/listing-09-25.sql | 4 + .../Code/Chapter-09/listing-09-26.sql | 4 + .../Code/Chapter-09/listing-09-27.sql | 3 + .../Code/Chapter-09/listing-09-28.sql | 3 + .../Code/Chapter-09/listing-09-29.sql | 4 + .../Code/Chapter-09/listing-09-30.sql | 3 + .../Code/Chapter-09/listing-09-31.sql | 3 + .../Code/Chapter-09/listing-09-32.sql | 4 + .../Code/Chapter-10/listing-10-01.sql | 10 + .../Code/Chapter-10/listing-10-02.sql | 5 + .../Code/Chapter-10/listing-10-03.sql | 18 + .../Code/Chapter-10/listing-10-04.sql | 39 + .../Code/Chapter-10/listing-10-05.sql | 36 + .../Code/Chapter-10/listing-10-06.sql | 36 + .../Code/Chapter-10/listing-10-07.sql | 16 + .../Code/Chapter-10/listing-10-08.sql | 15 + .../Code/Chapter-10/listing-10-09.sql | 16 + .../Code/Chapter-10/listing-10-10.sql | 36 + .../Code/Chapter-10/listing-10-11.sql | 2 + .../Code/Chapter-10/listing-10-12.sql | 2 + .../Code/Chapter-10/listing-10-13.sql | 13 + .../Code/Chapter-10/listing-10-14.sql | 25 + .../Code/Chapter-10/listing-10-15.sql | 3 + .../Code/Chapter-10/listing-10-16.sql | 18 + .../Code/Chapter-10/listing-10-17.sql | 37 + .../Code/Chapter-10/listing-10-18.sql | 18 + .../Code/Chapter-10/listing-10-19.sql | 46 + .../Code/Chapter-10/listing-10-20.java | 26 + .../Code/Chapter-10/listing-10-21.java | 18 + .../Code/Chapter-10/listing-10-22.java | 19 + .../Code/Chapter-10/listing-10-23.java | 31 + .../Code/Chapter-10/listing-10-24.java | 12 + .../Code/Chapter-10/listing-10-25.java | 19 + .../Code/Chapter-10/listing-10-26.java | 17 + .../Code/Chapter-10/listing-10-27.java | 13 + .../Code/Chapter-10/listing-10-28.java | 28 + .../Code/Chapter-10/listing-10-29.sql | 5 + .../Code/Chapter-10/listing-10-30.java | 36 + .../Code/Chapter-10/listing-10-31.java | 33 + .../Code/Chapter-10/listing-10-32.java | 69 + .../Code/Chapter-10/listing-10-33.bat | 4 + .../Code/Chapter-11/listing-11-01.sql | 7 + .../Code/Chapter-11/listing-11-02.sql | 9 + .../Code/Chapter-11/listing-11-03.xml | 11 + .../Code/Chapter-11/listing-11-04.xml | 5 + .../Code/Chapter-11/listing-11-05.xml | 7 + .../Code/Chapter-11/listing-11-06.xml | 5 + .../Code/Chapter-11/listing-11-07.xml | 11 + .../Code/Chapter-11/listing-11-08.xml | 6 + .../Code/Chapter-11/listing-11-09.xml | 12 + .../Code/Chapter-11/listing-11-10.bat | 2 + .../Code/Chapter-11/web-examples.zip | Bin 0 -> 38798 bytes .../Code/Chapter-12/listing-12-01.sql | 8 + .../Code/Chapter-12/listing-12-02.sql | 26 + .../Code/Chapter-12/listing-12-03.sql | 9 + .../Code/Chapter-12/listing-12-04.sql | 14 + .../Code/Chapter-12/listing-12-05.java | 53 + .../Code/Chapter-12/listing-12-06.java | 10 + .../Code/Chapter-12/listing-12-07.java | 14 + .../Code/Chapter-12/listing-12-08.java | 13 + .../Code/Chapter-12/listing-12-09.java | 13 + .../Code/Chapter-12/listing-12-10.java | 80 ++ .../Code/Chapter-12/listing-12-11.java | 66 + .../Code/Chapter-12/listing-12-12.java | 31 + .../Code/Chapter-12/listing-12-13.java | 68 + .../Code/Chapter-12/listing-12-14.java | 70 ++ .../Code/Chapter-12/listing-12-15.java | 49 + .../Code/Chapter-12/listing-12-16.jsp | 1108 +++++++++++++++++ .../Code/Chapter-14/listing-14-01.sql | 22 + .../Code/Chapter-14/listing-14-02.sql | 38 + .../Code/Chapter-14/listing-14-03.sql | 5 + .../Code/Chapter-14/listing-14-04.sql | 3 + .../Code/Chapter-14/listing-14-05.sql | 4 + .../Code/Chapter-14/listing-14-06.sql | 13 + .../Code/Chapter-14/listing-14-07.sql | 26 + .../Code/Chapter-14/listing-14-08.sql | 3 + .../Code/Chapter-14/listing-14-09.sql | 5 + .../Code/Chapter-14/listing-14-10.sql | 5 + .../Code/Chapter-14/listing-14-11.sql | 9 + .../Code/Chapter-14/listing-14-12.sql | 18 + .../Code/Chapter-14/listing-14-13.sql | 4 + .../Code/Chapter-14/listing-14-14.sql | 18 + .../Code/Chapter-14/listing-14-15.sql | 15 + .../Code/Chapter-14/listing-14-16.sql | 5 + .../Code/Chapter-14/listing-14-17.sql | 2 + .../Code/Chapter-14/listing-14-18.sql | 2 + .../Code/Chapter-14/listing-14-19.sql | 3 + .../Code/Chapter-14/listing-14-20.sql | 9 + .../Code/Chapter-14/listing-14-21.sql | 7 + .../Code/Chapter-14/listing-14-22.sql | 3 + .../Code/Chapter-14/listing-14-23.sql | 3 + .../Code/Chapter-14/listing-14-24.sql | 2 + .../Code/Chapter-14/listing-14-25.sql | 2 + .../Code/Chapter-14/listing-14-26.sql | 2 + .../Code/Chapter-14/listing-14-27.sql | 4 + .../Code/Chapter-14/listing-14-28.sql | 5 + .../Data/loading/appendix-a-import.bat | 1 + .../Data/loading/appendix-a-import.txt | 1 + .../Data/loading/chapter-02-import.bat | 3 + .../Data/loading/chapter-02-import.txt | 3 + .../Data/loading/chapter-03-import.bat | 1 + .../Data/loading/chapter-03-import.txt | 1 + .../Data/loading/chapter-04-import.bat | 1 + .../Data/loading/chapter-04-import.txt | 1 + .../Data/loading/chapter-05-import.bat | 1 + .../Data/loading/chapter-05-import.txt | 1 + .../Data/loading/chapter-06-import.bat | 2 + .../Data/loading/chapter-06-import.txt | 2 + .../Data/loading/chapter-07-import.bat | 2 + .../Data/loading/chapter-07-import.txt | 2 + .../Data/loading/chapter-08-import.bat | 2 + .../Data/loading/chapter-08-import.txt | 2 + .../Data/loading/chapter-09-import.bat | 2 + .../Data/loading/chapter-09-import.txt | 2 + .../Data/loading/chapter-10-import.bat | 1 + .../Data/loading/chapter-10-import.sql | 4 + .../Data/loading/chapter-10-import.txt | 1 + .../Data/loading/chapter-11-import.bat | 4 + .../Data/loading/chapter-11-import.sql | 8 + .../Data/loading/chapter-11-import.txt | 4 + .../Data/loading/chapter-12-import.bat | 7 + .../Data/loading/chapter-12-import.sql | 26 + .../Data/loading/chapter-12-import.txt | 7 + ProOracleSpatialCode/Data/loading/copy.bat | 25 + ProOracleSpatialCode/Data/loading/setup.txt | 41 + ProOracleSpatialCode/about.shtml | 38 + ProOracleSpatialCode/code.html | 432 +++++++ ProOracleSpatialCode/cover.jpg | Bin 0 -> 47561 bytes ProOracleSpatialCode/data.html | 161 +++ ProOracleSpatialCode/frontcover.gif | Bin 0 -> 7120 bytes ProOracleSpatialCode/readme.html | 165 +++ ProOracleSpatialCode/software.html | 33 + ProOracleSpatialCode/toc.shtml | 33 + ProOracleSpatialData/Data/app_data.dmp | Bin 0 -> 509952 bytes ProOracleSpatialData/Data/app_with_loc.dmp | Bin 0 -> 653312 bytes ProOracleSpatialData/Data/gc.dmp | Bin 0 -> 9459712 bytes ProOracleSpatialData/Data/map_detailed.dmp | Bin 0 -> 3508224 bytes ProOracleSpatialData/Data/map_large.dmp | Bin 0 -> 35082240 bytes ProOracleSpatialData/Data/net.dmp | Bin 0 -> 5285888 bytes ProOracleSpatialData/Data/styles.dmp | Bin 0 -> 436224 bytes ProOracleSpatialData/Data/zip.dmp | Bin 0 -> 12288 bytes README.md | 15 + contributing.md | 14 + 380 files changed, 11850 insertions(+) create mode 100644 1911.pdf create mode 100644 1930.html create mode 100644 2443.html create mode 100644 9781590593837.jpg create mode 100644 LICENSE.txt create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-01.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-02.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-03.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-04.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-05.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-06.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-A/listing-A-07.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-01.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-02.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-03.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-04.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-05.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-06.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-07.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-08.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-09.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-10.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-11.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-12.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-13.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-14.sql create mode 100644 ProOracleSpatialCode/Code/Appendix-D/listing-D-15.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-02/listing-02-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-03/listing-03-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-04/listing-04-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-03.ctl create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-04.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-05.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-06.ctl create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-07.dat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-08.ctl create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-09.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-10.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-11.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-12.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-13.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-14.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-17.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-19.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-20.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-21.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-22.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-24.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-25.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-26.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-28.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-29.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-30.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-31.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-32.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-33.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-34.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-35.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-05/listing-05-36.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-19.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-20.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-21.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-22.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-06/listing-06-23.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/SdoLoad.java create mode 100644 ProOracleSpatialCode/Code/Chapter-07/SdoPrint.java create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-13.java create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-14.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-07/listing-07-15.java create mode 100644 ProOracleSpatialCode/Code/Chapter-07/load_geom.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/oci_sample.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/oci_sample_array.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/preadgeom.pc create mode 100644 ProOracleSpatialCode/Code/Chapter-07/pwritegeom.pc create mode 100644 ProOracleSpatialCode/Code/Chapter-07/read_geom.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/read_geom_array.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/read_points.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/read_points_array.c create mode 100644 ProOracleSpatialCode/Code/Chapter-07/select_pois.c create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-19.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-20.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-21.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-22.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-23.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-24.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-25.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-26.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-27.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-28.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-29.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-30.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-31.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-32.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-33.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-34.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-35.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-36.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-37.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-38.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-39.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-40.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-41.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-42.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-43.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-44.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-45.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-46.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-47.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-48.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-49.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-50.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-51.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-52.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-53.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-54.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-55.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-57.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-58.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-59.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-61.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-62.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-63.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-64.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-08/listing-08-65.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-19.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-20.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-21.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-22.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-23.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-24.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-25.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-26.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-27.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-28.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-29.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-30.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-31.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-09/listing-09-32.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-19.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-20.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-21.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-22.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-23.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-24.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-25.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-26.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-27.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-28.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-29.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-30.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-31.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-32.java create mode 100644 ProOracleSpatialCode/Code/Chapter-10/listing-10-33.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-03.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-04.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-05.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-06.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-07.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-08.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-09.xml create mode 100644 ProOracleSpatialCode/Code/Chapter-11/listing-11-10.bat create mode 100644 ProOracleSpatialCode/Code/Chapter-11/web-examples.zip create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-05.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-06.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-07.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-08.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-09.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-10.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-11.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-12.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-13.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-14.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-15.java create mode 100644 ProOracleSpatialCode/Code/Chapter-12/listing-12-16.jsp create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-01.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-02.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-03.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-04.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-05.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-06.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-07.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-08.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-09.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-10.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-11.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-12.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-13.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-14.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-15.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-16.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-17.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-18.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-19.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-20.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-21.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-22.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-23.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-24.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-25.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-26.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-27.sql create mode 100644 ProOracleSpatialCode/Code/Chapter-14/listing-14-28.sql create mode 100644 ProOracleSpatialCode/Data/loading/appendix-a-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/appendix-a-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-02-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-02-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-03-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-03-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-04-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-04-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-05-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-05-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-06-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-06-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-07-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-07-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-08-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-08-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-09-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-09-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-10-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-10-import.sql create mode 100644 ProOracleSpatialCode/Data/loading/chapter-10-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-11-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-11-import.sql create mode 100644 ProOracleSpatialCode/Data/loading/chapter-11-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/chapter-12-import.bat create mode 100644 ProOracleSpatialCode/Data/loading/chapter-12-import.sql create mode 100644 ProOracleSpatialCode/Data/loading/chapter-12-import.txt create mode 100644 ProOracleSpatialCode/Data/loading/copy.bat create mode 100644 ProOracleSpatialCode/Data/loading/setup.txt create mode 100644 ProOracleSpatialCode/about.shtml create mode 100644 ProOracleSpatialCode/code.html create mode 100644 ProOracleSpatialCode/cover.jpg create mode 100644 ProOracleSpatialCode/data.html create mode 100644 ProOracleSpatialCode/frontcover.gif create mode 100644 ProOracleSpatialCode/readme.html create mode 100644 ProOracleSpatialCode/software.html create mode 100644 ProOracleSpatialCode/toc.shtml create mode 100644 ProOracleSpatialData/Data/app_data.dmp create mode 100644 ProOracleSpatialData/Data/app_with_loc.dmp create mode 100644 ProOracleSpatialData/Data/gc.dmp create mode 100644 ProOracleSpatialData/Data/map_detailed.dmp create mode 100644 ProOracleSpatialData/Data/map_large.dmp create mode 100644 ProOracleSpatialData/Data/net.dmp create mode 100644 ProOracleSpatialData/Data/styles.dmp create mode 100644 ProOracleSpatialData/Data/zip.dmp create mode 100644 README.md create mode 100644 contributing.md diff --git a/1911.pdf b/1911.pdf new file mode 100644 index 0000000000000000000000000000000000000000..331946a2556e120dab314b84832133e056dfcaf7 GIT binary patch literal 422603 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
Mks? zb+x)Cq=dMfhM2$M;0qhYrLCbShgh)r$?T&-n!c)>^?E*d`Et!)@- znF$0IZC%gydjYDN2 z#l#laDy$AQDBVZnW%_W2^)26Ldh&7{Vl-ov6TDMW8^at6dP>>{X%8ID<(K8cpNIkp zPeB*#;aa7fVr*igQ|CnPu{Kxk-X3BlbIeN*=0jTZo5HxT+uc237G@R{Fr9A+X^hA0cDB!V~Y`eZlZkqQGw$d^=qd(6%HLC7@>&s7yA z>=@5w7`rwu4tvP4kbSnJ+RVP01~cn~0gSl~P_{eFv3UI(L)80$!q5Ns<>@|K9G?{t z1`70a_!5_|`37D98zbNH>s)76In zB@ux!U69M7P)nuUBp!vxMhLQ#IHrZdy_JmIN7Yq^x0XZT#Sq-^m!$yi!nD!pd02LO z=xef;YR7Odba2|Wnxr2=PTaN(rlFy}nW*b*d`7y)fPqLCQ^n$VQ@;%b1>$1y`ZIs# zI_>B6x2+D2AZW1s13}V)z`pw!&l)YyY|Dg5-Iq>X=_^Lh^1@3oK?b{{JG$e}{8#r+ ze01vMdmX0ioM4fjf~EpoL5l^b`D?IocQe85=7LJ|DupVxJl)gR|CI~S)Zu4o=_b3SHJf7$@w zj$?A=;=o@pe3{zr+~iVmyr($M-oEByHbfX~hp|?}F+g@7S#OGELtS}Nk=Az}KHUGd zh4sL@doDWb0|44T?E1|={p^!J|9Y?3^k%^1%Lf4!?F~=WiP9W-jMnlV$8quju zr0Ni3d!zvp{-*B2xy-wmHJ~?6Z5@4O3fr_m2H_*P263dxT1iX*<|GzVvo$u*w->jH z!o7f5F) zwKc0(mr=p}M+K!hHQbT2okpwjV(V-5M`FlQOS9ERTk16wm%RVZ$>09%lg~dm_4i+R zj1opNJVOA{Qn5tTLa|3fhvpnC-4+iw_RmMck{AuyQh7aJT3-=wU%i$o-4hFVU+5I%KU4zK5%<5P`kB|KdYnT!NkfN9wL&*yp4@G zj!@4x!BwDjLjwctM(Cr1%~}}HOy|W!PkuGGw=!9{zbRc<6EF9_n|pF~cQ1QaeBksA z=bUnHd*yL!skLw*e)n{vzNjqSx_@5Uy)4XRg`1Uke|PfJ&;I)9sgK`1aq_TFyUgz= zr(UP z!Ti(u&X22my(jsWtTpW_o>eaZPp9Wwi8xklQk+5BRd-eIBCF^z@W74fJbFU^|y9Em_O_f z^gdz@_FDrHV{r`)DSCZ?wu!MVk}ofbi)dDv4{Z)*G@Ffl&GNZpKya{T%1 za1xW@wKC&oGJcQzmyckMh*iY=GG}_kcadXVi8Mf{)G9)*Am+vO>gw#w%xl_ZaWm9h zT*BDMAf>quaHYaoCtn&E7&!aID+!G#9CIUlj`>^{`2pw#IxHCNgMrmB)VLRzGj^X% zwD#+&wX)rPP=1ZBaQxM|*Sg+3pUG@gwXRJz^HXwTIse$qN~_Pe*Xo(ZMrM5Q^|q)# zoj=%r|I7#PIle*cLl!d@G=&-vFTm#ucgruSL1R~-0`=?>JjQanC?b~4Xyv*ML`|L_ zy^w__&J$+#f`<;2;*m4GRL7$Z^cC>h*zOkeWc*=|yUb|I>yn5*I|qdfvWGV6xplUZtLzk-+G z8Ozs3t{W8O^Q)tc`AZ~vxZu^trltqMx_WUeYgtsG6v#&x23ibM6;dS#?ijdq+d_t$ zBQ4Z^=AYbl_wK$}Y8Xq6ZdRDw?aYq-(R4dhydX z{GsAH=u1D=*mFK3B72&_w@Igzz;Z+f`{CLbXtNGrCc z`;WV+iHX&PV>F5X(6!4nGd&ux|6cya-|Bube`2{^ihI4hUyI4cXdS@z>mGFlXPGR6 zPz2fijUHfk4 zC@?(kO5KvVWFI^CGOe}~=|aRwp+gWfhn?Z>K$#=(# z3sC%~a5diIe4l$Qvtzq$!}|rRkCJ5CUKY7l_p~yzx7ip@F!TPPakV=sk$0%Hqa24`}s7Zw)T^b0ugtn+@*n*N?-Y8b9dbzs2xjTi;v-$!e zL3D{(bSacw5}!RAS8Xy(9 z7NV+Uai?o{ZP+0?tH(^nZ48DPj>FuZ$2wh)w;RCXH(&nsw{C;FaJ9MG%%vJkT@LpJJKvF2w8iD%;%H)$*pUd&0JH0mVKC}hj?(9@5AK?b)tTi$Bz*q$ zZhCWeZEqpFdCB4LD0CvOe&7O}p6$B6d6VoTDa&G?gcQrnE@|tjL5WGY$Yc{*gj1~V zLLfD0?f9N ze@X79<#6wVq&$FDb8z&Y*UX!ikGjhHz1@wKUbKcJr4E94z1 zs<&~fc&Foe4i`1ij67Lx1ihir%nu*rICa5Zv8Xs`+PCzLl^x$0Drm63rYS)w$hbl9;ujoGm zVdl}K#Zill`-UlQUEY4TFB7sLkTUN6{JDs!2DB2RVjghwEnB7n`2@y&Lo}Py-+l4N z&)x*C<8mpaK#;}&(ut@s*bh%I(r38-z(~!I!v_~5f15?LJqiNr?bCmwHZ;f&O;LfR z@`chOpldo5uxpto#cV0Po_lod?|0aR>my<<;rl{m@kB%AOPUaW20k5g$4%aRxSqhe zI$Yu_Z#s-xxIo_y8n^a}TD4p(>v8^mh;2Mds~`F8yq~^tQ zF6cXzbS=N~L@O_*S^e}Knt<|0ymPO`*MBB4A!uMEzI`;}cOIXdqD_p?;aP(GOT35N zZ1)@<_5``h5@@c@!nEE{@LcGc#Vx$OV@ub^0SrcfT<821Z*)I7|0@bw1blHO_JC+u z&=)6~@+Hw}ngI%m{cLA!%5uV75T$-L*Py_CzEbRjG8!69l+}SoTO=IBlB6H)o&0C0QF%GD zo2jjD6gJBHvnfo-qK>kzj!>g(*_&%8J_CWh0h$r2>ekgzqLwt6V|0S3E=_C3k_PE9 zU-m^$e0pA=no_p#$07GFT=Mxr;F4#+`=HC*cfvt?Aczq82LJe6@-y3Hwom{c`IH*` zRv=Uq7Ao5a2SI;HO^&Z@nYgc>+Mo!(1;Y;}E5}$S6a%uO`%oNL8y9{fVHDW(p==>j zTCOea7IV9q^Q?FIN}9w$Q+6QRP}@%Qde!_qb7j=MbanX0^>pp}ML2*%(c<)rir_E7 z7~hQVWnr9}%E4MZGsmHgsj&Rei+Uw<`=3dqWnBcT?^eot*?cuqscLH*)$-b2Zo71M z@ql%`rI7$ZHoQFF>ENniK7B}_mN6}kNwfa}dn2@?P3R+ypoE+}(-5i&7q=N#26vYG z=$riV)x?d?-An)I1b$1@C}vw;IB?Iy0P7AvX#eS}-@lh4EWmY{X9gGY(1E>{6r5ZDhEQ^VhUd*kb^t@Xu6nJE)sw)<}phHW7l0$&@} zzqXcP8)Lo=cA8H%nW^^~z4=VRlDLPs})Q zwcx$)%%oas#}SA;`={WDM&@oeID{us=e`Y6gt8xJ?|`?yy3tVH&tF&M`Ti z6YA!ZcT)FyBCa(NnGn8($%T@u;vdm0O_)Jb7Cr0<_v4q$V^8ltY++g4Zrkp)@hdC& z1#Rg?Dm~2GZ8}1Vx;H7`fNZAnw1{K}&TvA{6;}&uLqkK?{W_Dc!3SYRTnOWG1P95- zxw2M9HY%6?pR2`UEJc;#f?ZiH=XbV}o`Z+$x(*L|i+foulhrG^(q3&owbTjRI!wz$ zNI1y|^B2?fJ2IdIc>00~zB$TEiDK;Z`jG?dNlgyi}#LQ1}8;OIJKSym{(SNej{?cYbI_VE>W;)CyZ73wc0gAz38-IZL zFb2n%0QRoE+SRTN21Ao}GX0^`bf#%$AO&Omf%j9=N_y{IWqPip_w?4On2~o^LVE9> zd(J)Q=DF2}_2tFc6Dr~Viu9$dlJV*xFzH`){Ykmu09)7KTMSv(n!y@o-2_nb>c&(% zbEXQt*4Y}XZLHTf*OrzWmAQQh;Z$!90^(pe&J2;Pdg#AChM?+p=9@fs3=Wo8q7 zs$BTz^v5m*U3lF4>}BAXA|@jaK4-KMn&|%M$o=_mYLzwT+2+y&(^GhYbk_%Py*=;f z@smdot#&EQvLyGwP&ew*+?{^}l*k^I--<}>_${AOx0ut>P=|u#&x)xX17YEX198CG znqGg3La)_9p)jk|n^S+f@o7sPgiS@wCL6}~q6%XZdl2Y=rtjUpc*`|tx_dPsd z#^2O)ie;qki}8-P>tm;U%c34~E3EN z;5J5O)0mK9oYg%8+QULF3_q#VHk{>+FTZ*)^7+WrnPZDBGF6X6_?r(-yiZ=A)1zQ3 ziif}rPa`3*%Y}2`pvobZl?axLElkeET&Pu?fR0cLk9$q2z?u+)@?>^}m!!^3Ld$wd zJaugJqUtE*A57I4N-;_72l72*6`b$9`4BmP9Uulx+`-N1)fC?}8LBAtcCiT6rPYVE zrAL{)%9E{SpfflP%;tBe^r-rEwQ?nAiHv;uPR(AwdFA%y;d@Qx2}IF8^#ZlW(S$DL z{f%;?rQ0+X@Qym^fKr;1#qNzZ7sSw7Yl$7xQul&417>mQ^C?Gr)DsjVrnZELF_uw~ zc=+Nu*!`N5of?h%6Q2zS%%Of?;-Ck|!%FU!>$O6V2b@;!ui0Q%`Ag|9)kbag>C$CHl-MH{ zx-5ufbV=O>{{WFd>%S-qO4=w`fVkRD=t3fQsJBmKrlfJq#iX(*Ya3!C&U~-&W65+Y z9l*L*!UN)f6z?QkA??$DVNqa#-;7uDqh77lYRhwzkFE_vX4-ThgLgkZ|ML%@6Enw0 zg$PxCMXluR4D4+zjVscNGG<9x5Z zb+R9G{0a(WEDdEppcDtk{e{I{>iP*hRgbo*bLS>YlCSy&iqf2|Di&$Cuv*gSbAdU; z?12o-MJe|Qh3vehI8LGigh(_XeH+c5O}U%m>o}Fw<$G8Ec3e*WPDYXFy?^fAUMoq$ znCZfgLNI+n7iN*zVEL?Y|KI2j-slP=X<@KWwEk|Y=>EiXf`*1U) zHz-MrB^`D+I%_-+)7f<&mP?PF@@AzJ zz}19|lil0J{?Jo`qiIWCxth=z`YwPkq^5W0do0?w8p1GDv(-#s18L6ig2bk>DpcLe z2{lRcSNT7%E$vd+hRTM!F+NIhyzHdt@-6^xrCNVnc87=mJ}iCt;m=O|^2ff{1iUcU zeN30W*L^ghlHCr$D(V4SEYvjGPiL&vhL&werPB{cdTrKq5eY?x7r8y-(N3_Yx(oc!G9iz|(KtaTX*fq}x*P>{Bc0 zEe6|3OSkzJny7Poe0*+#{YZ})(N@9mUo-mFs!p};I!>+bEIhh&`uqhY-~RTq-}^hn z#sn@|VU8S7a^W>KBaR>~BC-emfL$0sUKWrSa#k3J4n4&S*xwAJ9#*A4Ry6ob_ZrL171(@b<2(V z>RRbif-#5H6gJe#E__5RLhK3XWf)O6dCRlSs|+Ro4&eI)Sw%2alSTjxYkx|L>{rs) z>8%P&{U+&_0HnJM(-B(z8g-R?1^SAuvD4)YUiiaWz0N2Kn^t;)p0>-JoWx1=G-|%wrfVB!&d=`d)mC-Xx$!GteVTDgQ4djOY6ajrn7kRv*s^o|)t4Wy&z_O~Cm+1$ z3ldSk&kseqeM_Brg3a&mQ4SMX!?hS8W{4=O0-BbE;n!cM4=B3%DSQduA{5yYp2FGf z`7%!x{2c0Z#AKSCWUjjh6wLcU{x&ot@HOiaO6nk*b9;0XS$4g&X4H3pux|dZuv%^= z&^1ghr@nl5n|fSi5g9Sn$Y$GOSqr@&3aQ;hUZE|_HRjd?9BB)aBs5&L*gx1Mhd8a@ zqMx7t+=OSLxoyMeCeesYl%V}&M$p2<7<_whvg&5&R%?w~#i{aU#!uWhJ#_xUJ0E@i zo`fG@$3s5g?Nb^!#i1xHv+#*q|@PUoAWKR#)t%OWHscZJiwjfX z2r{lSgxLz)WVLrOKUFHRsa6X_%Ii4CU7u2`8i_DiI6x@nuU+^AHVlLu>cKL=I6x?U z3M6bCZkB4ivc9@;?{OuU=R@4Bnbc%EF8)`3Qkhg?rZOl%*DTcb7E8-R`YS{Foo@H@{PM0V|0(7sRv(roGqZD*!u;}jX13>O zyT9Y~sT036e5m5Jgx`3`M{67@8Qw^UCLRUL(zT}D>#?4oDOT4w{`4=O>+Q)*uXWEk zR7kb$)Ck_NAwl>982%i_;RS^Kju0A7o43Qp)4;NTw^k$A2|baL6!AB3yz{8*Mek-T zmoBFf;p{u3P_a$U$DbC9eSJYa@VM_e7Ku5h3oU*M8j>ee-v7-nEg&vZ-lJizWAu&_cr8ChTx8F(aL0U~X=`K}owaAu%@TITYdiZ@ z=cSpA#oW0A6VqNxYA)-sTvv!O_HE#Yw}QZQ980Jjr5pq|0(_Yg*W7#l3LVQt6Q^&G z3wUq1VDua?Jo7+sk?oC_)457zF@mq86#UL$q`Fr0nEreYcAMN3-sO7?+A}GkFerrD zi43V891@`3CRUvXTx*u?d#L{}D5_%1$7b2rMCF-_HNkw`nufr|!T^OTy5aZ@VAlsb zF89n0eq5}~u2-hYsd8%U#ObrAKY%JU9UFW%tjZAVfYUFUv{(a@#&v`ZV#ssfA#MJl z@lr!u3um>6P``^0mX}kNi(^c9=`knbA~_*`gn5rN!%v+$+VioGhU2DqZ4$>d%i;Eu z^4j9ebKB&OPqQ@>0rouVTUL!wYP@hoFM^>;HoaQR7d2_N_2y$BORs*CDR<=`97Q%F z{6NKy%%t!i)qf;CrN4U4-5m%7FLX~=d(*CG&UIT>JD8x)m?s3s4xv>J_GWr;7BZ>O zf-Cx+s2e__V;RtG6S6&g^TQt2`Ny$TW+hWuSjqh1vrm58Bz#YliSS*7FtqjouzeD* z3!|JnaL^2dlnD|F3r^V>3xwX{N)47o?+zSx`lxb^7&|zx6RW2+4-3{*9hN<d!B0x+YkjI2FfU!D>qJeAGNtdq=UN5CbGxnM(q5@XXNC zOCmVy>4mV}ecs6v?HHrY&PVxd?mVM56=_MN)D@965_2&h7#3#m;4rk1q8!76gWqfn zj$rK4e=OUk%bM1=t?iMm+^g^A>xFODR(4;`yd3?>*h%}`vt56vxKt<=mP!$PrFg`Z zMY*7U6xOAZIB71uo>^RfeC+@?11p{<4N2iF+k!M8wE_r1Ct%@iyYdYXzO0>g%-<3Y z#2Y2gi3=S1?~w;hRM}Om%J5d?GKhZ92~r3E&){$cgjmo(eTeqVj6*DOsU+1Usdcc$yTXfu1;PwqVG{&E z9#{LM+Ihq-+YQbQ{_Tp1vnR5PlZOBM)2BTJ1?;!Lr}yo|X~ZuaJuKQikSeD?$ru>G zOe9j|98>}vMG-I`Cr~30>!FlEJjllPjW4|E?>z$3r!hGdKic#U#|sJd>tnZvAu!RX zaS(btN}=hS!!KNS^{anv7}cA*)32OwyPmclS8Tgnzf-Sm&bK&DC-u?gM+-R2$~m{F z8S%U7ErbFWk4m<%vXaYH2I_)T1Y}+$e2s6GvY2xwrealTv4uXvVQh@GYPR64=ed^0 z6(&hv;mMc!hy-P+7Yr#&gl6BNC{!p+#RZiQ(ZxbGninCyk^$a(AD#L5fXFlOW_BUC z3Yq`~ywsxf;^pk}&D1k5iXDNTLMLIeC9aP~Vl+%qE+^idMDTn_-*39MT36!WpQG<{&HYqW@5Lp)BG{@+BD}Lj7>PHS8V6r zvwDlV^K*sLMrt*y@GR<+u2!In%E0r5e7;aXYzx_PCXYs&*fVb%PD3IJqK4AMz}cVq zlt&{CxA8ZD+L$0ZH|=l}sK+3IPL7Sd?V@e)ihiz&I#elEUZES&2NJEfg&RW)$JuG@ zAov*!1de}n>UUR9?|X6^8TJ`wH|M3|C8=;$rTy1?yDrqd=u`DVAG>O#;u;q9YT$`= z*>+^x(u%}!^jijwAq@!hl_q>XzEtF|2mcL%>JS@gK(m%c+uI?m<<%|Ick7N-cj}Zn z4ZP6<+coGBzVSzb8w?$leCnU`D@vrth9g{51RVPWI$78hfor|qP^scMgK zLPObnSy~H|mW7iXb_XzS4bD6VFAzAe?EEPFCW+~*phAwKKj5t$Ch}@JHX0zsqYPrM?i@Ov2TMg zPD-`*$Q-rs zkz_Tn93#M)?ud#WiSdMkYSVEXuj$tTM=6Ur)0O3i>)Fz>L@+jHWzz}9Qor~I<%`m- zWV0LBagDCTS8XOwA~zZ+g-f~2xYT=AS}etlfSQlp!AXz(90***Xz44_s*5mn?Zltu z3v&L#&)DLr|8rgCPjMVq_>W9gs`7(NKPXPhagvG@S5mR9C`dvL03?AVK%Bc` zVV4CY&|z5>m+Zo^B}bBlE*2Kp-MOcyyIFIvo`;K=3WKj?GNfzeQ z3o&O=*qQ3AbI<<$Z~yl3(F1|8K*uED+t3Z5?icHi+&@YTMnWDZ>8#mkM4~8$IK|h6 zYWKM-r$B&>I*b)oH%@kjiB4v)xL_>nIvprX0vp;TA0E{A-{U5>Js-qXAqNH*=RoFR zLo#$H5>Sdm7k9nbzq#Y0kl9-|*9r@(#c~#?49C@&YoyhvR4!NY%ax_&E+My#tk7vu zD^1pW@==2Zwt_XPx)Qha0pw>p0W`*DnyIc*uAAD792u33#*RM(uGSy*v18xK>P1Ae zHd`gF8SGQ^lU=aFG4bN#PyhNS+Sr3#zL}Xc@QL?v*vkewd`4BMHJD(Dg(Q$m=0yr% zB_;Ur`JcW#ZR18TP=M;rIB4NN5BtRTX{h$3og@{f%vcO>#+N=23!kdQ23`%J(Gx`W z08v1$zpj9`u5R=?v5A3$%A^WgM5-Z`Io6jSiO$u^{Q7)8jm4U@t&ehscnb7NsaU?d zG&?Oz%xJcsOp%R|2oL7r?V1$!R8QhjccS>jq!z-Pi5gFHZ+ak|ZIlBV>YULhOQvuM zt!)cWNPI7pL}6wpWWhl8g9R=QN1aEG{iEY((-KH$TS$$RzY!K8{c^KyCb5ZoBCdq{_a9SMK`^dKZ_AOXWK)^N}$l9l|-u z*fKvCmhY@CjJ}CbX$S+|acXDj{&e4hkI7a>ZS}o_7u6wYJ08)(Ch!HT?F-fCc3YNMJ;AGIq^|VJQpdRi?DQ+y!a?p`4LRTqV%wUOb+#_lz(}y;y zNu{Jm6xR%~-ozciA2-kTR!S@DU-mK!ONVM01B@=^MVM$D=~V9RJBtgm_bR6Uwq&ca zrmt3L`EPl8Jztr-a=`H52`+kDha3dr9wiapD+;)Y9WzdG9pU$3r{#0AgEJmxW*QHj z=srlsYsNiUYm+ezQp^L-jkz5i9QpefM+VvOmA+yfYz#t-5{luM!64>7bryg+(#;hX z-|inEQG!=|iy*e8h*0hkR7X@$ISWxtIS}AzL`CR917o)x0Y*M`P%TdBMmhYzG00oI zjWv101wAxio)Y_bbu8#Cq_~S+j8cdor5JeZeh>{7ob6nmE-x0kh%vjQ>!!}-9pskg z=kG1FxUYUv;Fi-b%caF~MUF_tVsU+PeX;9+wlhTh{*sBfZhf!xR=RPR zDN+W$9!9b|Xuw@?F_{k;s2?68nO;Y}@MHoGf)J|5I)CLHgb|1zZ{J$jNj~wlq%8zb5_`Exemy@Vr`2wV; zyS=?zwQ(#82t|oPMFbp9A|CCa(i00vM3V+j$DhOg)qrMHzt;A6>}E&LjvOkO5{{oI z+v@=VUpC!$x7u&_bc|rg3vEU`*zJj6pU^W8ic{Z>-8_fXfP_;?B1sM`0j99OFuhc+ z6m-5y2c(t&t*4`MX`zrWF0CwA9!-`WPxSM5+<54LQSO{3@X;h%LdHN%;mjQ659k1d z4X`uIH3_Um!U)jGS3n#Xz^dv7YmpM8l1X(b6M@4Sq1GpV{`Ij42*rtF7r&qF*adNM zGWu}Svg9PBWSt^v2*KG4t4sOOCv7yor)*n1mZb2b`LT)ov#lxS?GXfn1r6NH%7#ll z-)Ulij$|ir5+?9c%9Vnu)+MYxcdNLtI@>nT+fSQ{A0OaSfWT4#UV{pOYAnRi;A?5F zmhsd0MQ@Q)#etB+oabdl1 zYkfipo-xXdx~fa#ZU?QC0H(Nd11hvo76z^gYKPsF8Q5u$k?&C!2T;2--!!bPimu<% z5CNqPoBr{mcJdO5=wn4V-wI)PuY|K8B>eXTmT8N70yh90Rt+Xh?$SsZsbWk&xcosPG^Fj9J4 zyuESa#Ocp^y3`rLxz7EnkGsKUvpnB&1g+k_JW|Kt1m90M4o-Qn-Hh9&L6Uh+DU})x zV?Hx6H+|>f9V0!PPvsUW<6mJ;M(ve{bK^hGU+!soOxHSNrcOVJlYo*Y&NGcl#aW|) zsXqremm1c3h<^rqjRv6@t=uHmnnSN?!6x|`GLzHjfF1eW@jo10CPT^2M58~-ggL*EW-Crb~9UjMN6U}>W|kYBs` z)AMUj?>*TXeNuShM0S#$rKBbNHBLvl_1T4QSI1|jChz@c=9{%PwQ(}zK!Dx@k>kn= zqLrh?iwl=55xkz8u>$x|!(&IZhTzufi4W?q5>qK|M2vwi2Ft~Tgue!w-)pAKtN_zMR>3^f(_4Q1?G=JjrTpF;LHG(O*;e$+RJn$(8?31Pg^FtSNx1I3D^v~FZ zF6<-rn?XE9aHdT$VN`qqM944C%qK~zTrw0orEi9LBG&oJDk+JB?CuJAwEAF4`COQJSZBCRT=O4X30I4OkC z5C|9(Am9f!HW(Xhv$l8{BB+#xkWvbv6oSET@9yk8?#z9isrsFnxp&4y2U_|i(va#@mQ@qzU%v~gbEX!qZkXpq1B{f_s3YT4$Z_h7y_PxHL< zMXK1)$`A_YZYGS_`@!JY)q}PZQ=VvF3Pz=D@@O{d_1e#$om-CwmcJXiH8|DV*WR4^ zcJl1v_@&N+;V%|4i-41r-PgvMt#WtpQykqpyEt=cc4qom-@#9eaEx<0)1gE{vdEMs zMVv)qLS`~ihw@mHuqOn(J?y*W@EQ1}wzV9VUD&jGz5lxNR##fyHkaeBr&}U;;@S(! zWo+1YW{5QnDJ>>bI1f|JO=f93h>}CLQD)c| zGkO_cWn45=9MHxmr{^Ya&CULGepTT}hPWo8<&zkb-oT&9OxY-J7yN4+F`>MX6(%li ze8BKOO5e#vGN^kt&ZEOOE?rujo|#^p_Z(e0tCkB!Ztf>w(xE5{>udPCESQRAWE+e- zD0YkzhZheH4W1sD&|+O9z`^@PKSrX1uR$nLc_%zhoB@yny_(jGP(0x{nWPeiG)dLK zR9^Y4+QK=DSIxJYL}@CyNVyh^*MITHKP=@zR>Z1uJ-|1!Ye~ZqRQIJM{BrE((DN-w zuOhZX4MKtLd^0tEetu1C>0*&MPHkb(ze z3UfJfq4o9X{LKByx%mcQTh2Or1#Y!&?$1|khCGt#p6y6?UgFD?2|)9Fl~N*(o{ViJ zV(^0R zSGnaygHoHyU+&nw^BHs)Q6uv6G;90w4%INIJ~g+r+Ben5jRLQz>NEW(E7=XAu-F@6 z^;#TtWH+@6d>Ow??253%_CY^L1TR^6_wAph5(aOjFZF@B>U@pxALQqd-B4&MChiHo(oFc0^|#(Y-}lPz zEh!+o8=zvHp}Y=>K+)&aCAIb8#XG0IKHX0w6RPK1{tG`n@q$F=2i|lz9u~#nO_tM( z{=dzgo&M_L)ryx}6*F(sU%qBf0lgxDsf?*{j;`NoxRcYX@oC;1$`@qLJQw>~NFJpEAYeh%O)4oLlyn(+co~i) zvPoup5{uB|SCCMxmXfrj$~Ag=ujmQg%5B^52C6hGYftr;CSWPvx98yDJqP!Fgm;D8 z&4>lUUYRMrVWU=`4;#jYGC^P-DF+YVpC6yP?ftUT-P%bP*X7Y=on!U6eiW0q?Q!E` zelAi#7DbtSHZFu*xIRBElGftlgN?85xf6P7uIf!l2tL#C9J~KKwcBfLuoD`=&9wbs zio8dr)Yif&^R8AIp^#i2XoVR(Q~Yh(|9$PxKTAy5r5wT1YPa!u+@GtO0zA#=ZrsM8 z0A4E;&g%@cs|bV0qC^>$!Rx}9NNx)w7fcbsHnTm_iVG_Og>}N=r8JR{I_42whMP@A zTf>SHlXVH{RnuSg?!~>Ev{$T3N^0~4c}=dx&V#&oonH!Ii9LI>>JMgZ~a$9kK(8kt%RIff?98naTlf2gStZ$feZPz0=7W8rE_l~iRoC;w(R-QMJ!*2RNCdpLZS!g zVj(LT(oIIH27v_y{F8Rs2(qgn_ECa2eg!ug(0XPRy@)(L`U|$pdaf(_a7a&*A6CU z&J6{({vkxGQH(S5<;l91)_G0BljoVM>n79-$@c<_r$j$YW4v)l#qr30o`$O{NZ6EV zNmucq3Mc$hu=D-jzP4pMBG;H^OjHq2kRKJMz;gq<+^vYIxyJ*B{wgxw7nZaLR)%RK zHaa?mg@9j0Sj8S7nzE;0cajp9T?vNs(ABZPt^Xy`41w~OZZq_P2tG#D{iJWJ6Gr})ws2A?fU3B6%qdC!w-%I zYWwVZZLl1$vM^2Dy zR5M&p{I9qj*;1sWb%sm!{+8%k8Sj({o$Grk>#(qgQZm;Fp$;k70Ij z?y;4P&#mQ`<=m7O3EF}^eKt8We*NOY;>Cqxpsg!4gj;1kTDUxS_44%hu;zB}o{v7u z(xSImHL#b-w5|0OK$cmO2z+Idn^2z6Z$VYC7vrkY7~42`Khdz8#qYe&TUc^2)YcK( z5>OZSrj6y1Dd!!rn!;10uz&`(BBTVfw&@y~_8O5&dpqCX^=8KjmG%?NrMV(r!omiRwc`M=dMsKG|2ar#d-AK7K%)JAfJ@xL@x zDQ~4}<5UvYUga&X*So%0W55Q>3z*A*!4ii+mPW_|8S063iIqa$q*PCGD2I-Nr3mjJj@HJXai6m7e`D&fZ5uANNTv3^ftFWewnZCIcvCIB zX(D2932a%^{q*b8pR{CR)7<|tEf<3@qhVc5*YX`n5-n8M2N~& z?_N#}2rT@9-{#Q^98lVE!c)bvcsxWLVC6eM;<=rVVh&M$CtF_J4+D=8;&8ruH@%Zu z%x4VYzS4xH2d|_bWV6e2aoYm&o=B8Us0Nq% z5p6##WHPbffEI?R7zIiEvO=aa@WFpH*hgHN*R-L|02(Ko2VFGyD_@+ z``kvAwyUgZ*^X5{{^IhV4t{@!Ir}uJlDcO%?0-OXqko72x z3#HOQc@}{rUQ~#B1f%40#XT6ImiqXF!8bU3?cT;@;#7wdBOg3ole0Y+ipWTaoV5Yh zI-WVo=H1fXhmY>t!QB_}np1mS^{m(XHLLRFXXidAW~0dUllK&eWO{G|Cmm+1P7U`X z)R{(Ns{~VUTZnX_@5&TYEzPP?d7O!Cd%buA&BgfR{cUDW@nR*8ip&XTkao;(jMp^* zxe0m9mhvZ6LEMKIMc@`lA%Vj;SuCC1yuYqy-fRay8!3GE;iKH*9S6!@-|$-Oi_QF# zdpFLQ=M9cNI66J-6DpxbP|%U92+dO5Awt>4A;e6+ zg6LftOp)*=x7x<;fEl2)Rm66_lbBpj8jrKRXTR-pYZ;?wyOjT>@sF0d^lCp*e!5at{F-XJ5oOR}z(MP(e=x>AU~xvXY{Xpj z)&8F+9tv^p1T6f?85zUKWODx;z+3z|v9!LFS>Bjm?!RRtV?hPPVGy4AAD+;4Jnq0$ z8c=j+;OZC2N*FA{P0a5x8e`xS66b^yN;?K zYO&(xvu18|eC*ZX?D5Xd(RAzhaCzT5kk^B4YG!7<6EVI8W?*mET$aLp9Muz;`{ zqVgNji^yDA#0 z=2o{BS43v;a&)pn)kJ3qj1Z#kp1Niy^G6ZvhR+Cge zs(d%hFBIMW`#wsrbLaMAr8YWfwr67Fqi_8pva@G_KOpkMEts;S*|W*V_m1S0;j z?lmNhf-El)dZ}DdXua)uwhC=WvXpen9P;b~v(2{a;*_&z!+1a4NZ*szWo#-oLBM_i%bynr?(T?P%w7o}IC7(ga8BiI7f_=Alq*a|sRD8dQyzDOyVfK$a zD2?5UzQQbz?N6^goXjm=#nii%X1PXbh1hS(6or_1C665x8LLv~)akFT6ucVo?Lcuk z72qV&fI9Y_Ka25ol^-a_qgu2z!I7r`^<0%JuuvU4@_NE@<@%__ZUEIju{m7%G`fn( z+R;5V`Y&7tW91US`1nA6JizYQZ-NuymJ}c5J2r!T@JY$OdCAyXn0+GJRrRf;>5cjI z)X+-7Y{kDH%P0D~2{F;VyvQi@Q$#UPniqAglD*)C7l@9-(2Q=@tt?QVG?|amTn4{L z>UUz}=pQie%O>Nl)o`hOVfk@#=ptne7e_Rxo7CfCe&`bF)XHF@OIN`=b?)>Y;ecM@ zXb?yimOnFbDGRDI*aua$+Ydt@GY+UxOZ5#o>H~HlDvosNH>TAikB$1g5K6 z*ibN?%A_;N#FS5;kM{KSThI8ifeQOIIlIRXXdMwFfS@2vRxIw>a{8@Rh&e2FfhyNh^^|yNSq@$3-ZGphg;eh zz;6((tb!OV5oK9z$ZZF6Eq66EaC-nMmgPCfXPx_1x>K?+T&!?$G`4i((%McUYTFQ| zC3U4T%RjB>hig7oi-nZv5P=!uu(JMHlstK#lP#h-9sUq6P)< zMsZ!?f3N>Q)kbQCN+hHzLX8@w34|nsw|R6iwpnZ(jPcum4fd|r4h z%l3L-Gdu6O_gvKP%+9@Y7j?kv_3Z4-z2`gM<0KL0EB2LaRN?P~K5Z06hU(W@n4qxH z5T?4OP0dcUzFJ{|Kj9}*8d;Zo&?`1CdqFs(;N>${)N@}&mcSXd_LZ;?Y~U(lmOSjC z9rI2`$2h%^TL_089oYUn`sVb=*3{(I()rTj6Kg`U<5l&+?aJe;wVPKO4G;3^v&ity zeBH`+pV`7(FuH)hxITLuVNQz?1L`o{CW{>``4x2%nY1~&Ihc4~Uevt;Ry!_sSQ>KG z-VU~y1P;IrIi%reu~g!$Y`pjPAOBMW!wVESk+Ih2fL_W{*dgIlXOikv}ejnu0>af@gW1f-%7*{(D zr@oEJS6b(bb@w*olOK%EPp@x0-Ml$?c5$PY1FU7bTI-=a^RMOE&8N3#d((gi&P9Go zJZ_j~DO%0ORByTXQH&IFJ4~GsWF~vyviQD5Z%V}Mn9vBd?;1-E81%_xkR~6gP zy;v|-W)ZEp4nHXJ+*||q5z<^;KxCxLxMG~`@Z~ajK83Isi*)k;6v+-U{2xT+Q3$Ri zchUJwfELX-ygOk47S;x^vZP%;zkItodw=QJ=thyM){GD1wX$AW{m1gnCqpPGy9cim zohV3mYClhnk#Pki1su{v_LBfU02DLdpp{Uo7;zS70xVaCk?uqIi*#A~D8Wo~-Su5$ z5!Thr6;jji**FG`&woUcMgim?7VVEdJ#iq&FG;eQjlU3j@$fhI&O516Q92SU-Uns- zDC*j0B}Vov6UNcxrL(ULPEc#}zgTBm(py0v^s_Z7^a|x?8Z$8cfpN*chnp{27a4Z< zzCaKqHp#c-w--Z@V05lD6snXJ96!G9D;c+7PG4!g{PQ%m1MD@ZyVzz0`RNxbRqCc3~A=oOw+y1R#p{u1Wd@It8=s z%1B#{kl7Qw*VG9W1@RoG#HJHw*;DrqAWQirJJQ~JyhN{4a`%6HWaOhXiqgCT(wtkQ z!lNfwj*eaWx~^zQVL*!5Y|;WcBfv%F3tpT3VpFfN+64Ajr=J#akFeXtf-Q(N&_%2B z^S7xxxIm79(`p~1t_4T*6Z>2tt1I<5Mtg{y(?b(yIKW(mdxae)jJX5KDjVU2)yl2K z%EOK814BQ|J=-il%l$WFaYo`hTj+qvl>`(_$#clgc4ircESU2yjl*!-Au?wrZ7b{hO6MyK9kQGb%H}smxya|2s)< z-hICR%TIq3sVGW>iS6tx0;papoj-iCbaejE$thLGV*-RvUm73`80Hbh89g4scY~PT zQe38=eIytf8bPbl9+Bm?eSU1DjRu!pU*}y-R^3*@LeP@Lg4-tGfh-sd;uzi41y@-A zehg_!CS6KG(I&lXIDkl#sbjVEwdzWxTKj5vc4hO?!{w@BZ|`?)b?N@2sm1O0K}V8# zu$GddS*2ZjUe9s5gl7Wd1X=S1hl>aZy9s;kubuIds(W-|u>%xoTc(cI=Y#@`InDMq zg$}6~M9tbx-Ss$dNxcA;sh;*4krqM)b&-C4@X!~(lgUm%eU{2!?ReB2C`Zx2smtMT zNwH7#^=P4jHl;Ox$ne+23|IHY1zSjahZe46re%4k);3GfSdqNh?Ffm{oGch(8?j-C zRp$Kpz4sW)K;M|1t>H`BO+<&|+JuT4U3?ho_7Plh@#FC6%k!%%cUP;Go0DIByRvd? zZ7q+_ImYW-cUGR>o1bbxZ(o6hMUUIUQCNvSH>_ybLH~DlB))#1K~Z9- z<f!%s@V`Uj>2mA|8Zh0ED);e6PggRo@|Y!ROz8a(LgLn-WAu zzL$ABWVuAZHxb_w9M?V>u7<(n3F`VcOv-s@Y>1F+L7K!E3kJHdDZpvQUN z37eX>2&bz%xVjOTCJ+`w`6%3KF%q9n{;;l>dGIZK+={(O1MHRb{ z!Cz)h9Xnep&D2hw9XR>0Vu725t-Fu!-(KF_xLXc+NO;55(xnsHhzk~2lxfA$)pMt3 zYZy9ddwxi!ikt_dXGwJx4eX{oCAdiY=@VFgJoE|BXduuJi1BqJ8Ly-JLarIS1+&F?NdEpSr4u!${`Frey2#hV*1j=_*iy~j*X4fb~)k4tPI)pp&G+LKzbNs%(=9tz4F>1O86n2yV0fa ze_U7ja~ww%{`2?;;1{4OPLV1qgmNVXR0vg&U>n~@WXaKG9cxLJby}8ItHZJrOh`yo zieD(Gkl2>2b63(HbM;JjzczetdU|HoqkDHW-Tl7feJ>{brgNs|epFbawWqA{*ymt# z7zx@!URt>MamOG_wbme1qPOzrZKVpXzj_OgSS@86r5pQU0Yq4 zdHhnMZSl+)<#{CUxXQ)+H;^wtPxtAyrG)>^-DGZgr|yo#^bfScIEmtenhx25=(`Q_ zZes`;yW25fYJ#o%NNjaB5jSTjudNk2(5sz`KmAP*P_~NfCY>|ibZ3HFXK?q!MT|9} zt099df+$HGd)eLefk&z{5S!4PlEL4G%!w}(AySshRIa3M7z*PI3Y{d8AGvlSl`2C= zkvBc>N#M`pn@d%$C3M?#+I^VZrEdFIUhKPm~z59`--scF+J~%jmK@XyHq7zxT59)NofLneTse6ICp8{%cYrK z=nT=SgTC*?1onHh{kNt_I9jQ0L=>=peR*Sg^NGdPMyypEv{Hm0E>$|LqUo(skpEIICOk(JFr(gJVFVNxQ}j!wm9F7>7x^nS=)~wDnVJ za(-IqM>qFQXopz9Jjn5Vq@W}>e#vAQV@Z|+k~Fc4Kx7MN2jt~J2w;4d+dlB`qTib- z%c)sqV=u_W8~gUg#bZ7?x=4O=Krx)*he?U#u4T zwJx3gvbDCfxU#mnS($`arH{?~sw#-${HVac41Ky&3Sp^HEqXWP6!3;0m- z$j98IRUI$4L$>6-T^d7ZGzZ%JC-w9w3k~Ut!29S#zJ1~6?~osG-|K1%&Y5#TgbW;V zo;hiZp6=!R(%eHe8!un{9g+>{N{EPn!3NVVt{5MTR3b}f1inM;Hx^BdBY;*49!iP| zSeL?0t&^Dm1|q!dEnQZ4o}=8eGDAqyd(5zz=%f3O*Pm@ZSp3U(|6OD2)9Ov ztDHdSDlVjF&rL}v>r-DXE;~HCzvFXly|!9idibpGBsyh$^JMUbQ|lb(uDLEFQ=042 zxr~GoII2!%i4u&A?i-xJQl9EWp$8(wva?Mlq$zl*Fy8DPVNcz$F3c;5fX!X$w3|Ch$d-hl9cL`@n)&0L{4lWv_=*3DR$!v95a2yl`b7Ddnr!zcW2GHhHTR>T%jJ zF28UtfGu#Z<;x(h58dfVYPV^Ru$^u9G(QaxxtZctb=??Wxbq(xLlAGA^Tq`vo~0sh ziYXiT>{xlS>rN~=x(@3!IzXC~pbH$GKmXT1&B7s)~P6=YYVu!-{W)QD+e;v@BZlzzx*}mi-xJQ zI_K%M*j7fqfcg-^8^*wb#>V!^;Tr=MGA|wu4GrUCXt>gc9K?l@)Z$c?p~T}4V@K8z zGzZhcI3_tbFfh>HKhQt_+#t*F{_F<%cEHvo{q2NPyO8!?kU5S~j+uVwH4ivB# zxL-W}k-U7R_cD4$qRBRfROxMw)9|1{j7UM~kS(eZb)f!vC)irid+nICT&-mW9!BGl!<=vV`v<3A#h#%PTu}rKH(+R5eudjCc zCK{$GJJVEGoHW{Wgxfl?k)2hmXQ&ZxMgL*tZY#L4{8X}njNYeFEWwP#vHAG z7R!j~CL(H1kM@j>z(l|Ua8RAeS{L=`N(xrDvB2^P7Q#3cg1oAuVf@tS`J~S$8L_fCKu1u7a0*I# zv2E}zYYiMvKtBY)29z+kzTzg{TA^PH_}Ur+U0t90>#z)!-)(#)Y)e?@?p-2*BW;)h zx2^OMpf)rz`-1tJcDn=c4}Zi-R^_9J+N-K%%rTk9===zo0Ie274kQ>f{`l7Wzug0~ zO*5?PdKbP$+29+E0AO`0OGt;xqc&6)#fg71H+XyLm|jj#R4SPLC}ow-T!q_h8CmtF ziQ+|b5cs2`)6bmkjsN4>;JrhrnwtBZG*qTvgdv>gUIizNbe;xs1*pOeErYlK7|Aeh zBvK)-0Yq;C>kP^mgC+T7m6q(TVM4 zW7anh#^(=gS15Z*4y^0FC1jQJ(gJ<3P)9-BirT9F=Nkv7qmZP>VcNsi+Vlem$QzG1 zK_h6>HVQ4k2z7W!7eC`3c#K@-wT%AJx%YPUk>A1mN1?EG<<=_u2;6N?nekmC8i{S7 zJmO#_bFeZvP$3<{7NP@6vw3#e=2qydz&Xb^&~$%x`SX=p)z<8v6ZgK}xHT(e8)-Mz zk&+fTgdzC$Nu@yop(xBBSK>>Kwk4!W3C2J1l_Zgj1;(<3Q!+e&W4aA`oT8yBk0Bi@x3|Me=|69yLKSofBJN>5{by!uyT@ArE=;V+x(q^1{p_5pBw49 za`oDU%QN3z`c$2yQhkB#BNbwnOQZ~aHqH*-IEI2luC|aIflNOdcgzFn{H2}`&YszQ zosL-a@5E{&w~nH4FsKgCki&D#gP^Sg&g~)y3`I@wDu~#W`Ne{(QWr7Dg-7?5A2pj+>Lp$VGAq-95DsWu!RS`ga7+O z`(OVQ@2-kWIfLs6BfqJc|Bbw^b7x4q7KG100z$Y; zJck7C?psT3#aBwXtXr;PI+@+r$RxAcy`M) zR7u4YBNL>=g7t+rQ^6**nFltw1Wt+#hxfd}5ZF|_TQ!&`m`njf5}M2$9T`9QJedxx zHy_w<-lMEselwHajp|JnsvHe<&Tn$aa9i6Oz@bw?nWC=VrQY^CJvTS^GVQ?1nAOIR zLfcT^*Cqh%{!GX1d)=VXu#@0ARFh3Zb0^Z89hGe(8i&RH^50+3>;3aIGC$D9)H6Gb zjNaNg|4>1nLD>3W?KO=eutSS?NYgdIS+EJp-NAB}g?UY;E*ypW5WL(?Cl59<&!bP) zGj5p*fGOE@I=8;DP>PMiL;5HWVhdj{Fe$jRHB+OJ*d znpoc4dDv-ikp@0MF0aBnjO(#I{JE+|s*t7r{MA2%yMtYQ5j5R)!!|gK1h5h^G(Zv< zjDrE2oeRivBL~GQJU+E_fVC#vTBo8T${>8YW?;S)9+A`V+=lLqCmz07cu|_&cFYSH zw3sVCEi5J1wsOU&CNt!94F>1TNvqLgZpQSY)P+RfEhZdJua!>(ohpFclpD_prV2e5 zKn4V-X(j-c)%XOg?C^2x7SP>a?P!g8&uuYjp>w5T0=t}$&x@-ebPgGC&hzB_c6w{< zU|hC6hzhaQ1$p+{-@*ps%`tOL4RU3JTwPyJBzNw#4S_e(zB~N?6?UWZ*3hk?{;u|} z=z3~MXEvOla$YB3k1|}KAzQN}lb=U`E2O`D{Usz3)h1Sr-W*P)E9IcG%j0U2b zeH>+ut*X2p%mh5e#85P3g48h`>lC}kH>74m)G?m|S8W_54+)T)jrc>&XL6-z`dQlT zZ$7_LEUu=D8~NqTYA-dJC%S|xgy9CWn)(6=2=ae~BCc^t205(tw(;FCuY@Mm!vDS!_`ToUo?rSDQO8aa&>GM@C z^vVaCT}WoPmrzv0F5a~cLxN3qi@^Nnxlx9#3%e&XC44#I<3_ zcEnOUU(OHSy?(z-fqAu=>8t>2^$KpG*t26Mlda#~{L8l$@Kb{O%XGM-vjT~fCkW<; zBliO!i9p@$wl`}A$K+S{4ej-)mHB{7;CWdWO_Lyr;obRMaqa^UJ45UQwi=j@)G)&e z%!6WT49m>x$HdHjapp;B1)7`lLk5^}dcAZXBR(L^kP!2=PPZe32`(V>)~Xa9LIyDl z?=QR|auSsV{k~FIGj-5k{cUX0XnYt?$U>w1k(@S;KUGXo`(>wDtyT@@^@8v;1aV_| zY(kdpp{b~^VDLq!_ULjxw6i{41t6Wvc4${O@)dM?d2bh%H;Z@v_29-osi-p+B60VQpIGHl zM^3$T>CzX5hOkN6QbuRLVJmewgPUT*24PU}*{Ou=u`sg?q*m6XpZY7PjEVN2hN4=H zBT1r0t$yuH5#Ed$=h7ZlF)klc`m1q@_s?n#VoAa=ut2?q#dz*uDgS&apUMSg%I4u0 zNcE6qP(=ap2hdkMiD##5MgUOveM5qF*h~!xpDT0q)9;=gook;SrBvC%n*KhXEDJlU z>(bc9cBD~^&K)c?(Szpu^Tk(@qmRr}Nf2$gAp;PJ#wHl9lhzkoq(SYY#e&CC7vfO> zS@}#BL@2Y8>M9^zmE0;4o)t}y3pl91t{2?bTV|gg+@6b*>5bLd)%4}rd;J|_o#a=< zYz0smQ_Zq&4s_ozreYh}TYV5@s9zEHF1#q``hxt&%fD9zg`5y9oKtgNvYXUaO;}*+ z3rcIi;Hi5YesaHDB}_b7D8{SW$K2b@@NO)r#&R!4UTGS7{#?*iMNzgEUeA|L#!EYs zwHE^`uw{8tqH1uk3kYqgAYIF_($(RK!n;6hytjAK_3cfD_Y?1` z2IW4_oF+3TaIgxD%%KA-ZtcN)8kmg~FS@QPIAN{MW&sro>l(Jb0AnOu66{2`t#CYB3{Yap@;X6F!ESd%t-61Omt20L#@XpJ&Y z4?F=l<=3HZ^Y34MBdTWx66w&Wfn!sQ!v=x{AtB7;Cj#@X#hntk6@(M3zw|!5*Hli^ z<(J>r#o6OzT}bX(BA%8G%lY_lIr5{lzx1XgN^|cPtCiIAGo??QuD<&?OGM@kE{M>} z>EcQ}NEzzF-1d~)go>8deyEsity;(!!Y)#dl-a2ybb*93O+kC^rMLK{iZIf zIz>lo)uo^J4zlNk$+_5%PxtHc-hUT0@Uq>+l^+=POwr;HhY+#0Tg|*UpF{%@Iy4I&HH!xt|M108f5hd7SK4wrNawGP5bus_w=|X(ZBVz5f@Jy)CSemT4p75(%>FiK2aX)!w=*B# zjwxE^XZbOzbsuJ%*6veeHY#aky?isbH=12vzQ6sWqGTVJ_e|+PZ;q>1SAST0f{mk) zi%iyRWJe$7q{xE`mnF;V>-ps~&2?ScG(}lyVBH{%@_Pz5BLfc1d}Dkt>X*ofI*(UR zl9M+i*X1do;CE(5#dm;_+b+89;fnJ zea@I4kn%fMCx-jm+IRBv+t+)bk}kH1#c9X4x!#_3DjYR7tq|q7c`$!HS2v0)fRjh=ZRBUc%bW_+T5N;l#q=+0^gdnOV#m&zI%&bA=hNA6Vtp z<}Fy`_QAHredWMGryCtSRy#w3ST>jhk&t2MfEHeLP$r{G7*J6#7E_&#TC=WBI$826VPZal2@Dz-(*B2D7{P`ei*n^knx(emHorCG*z<7t)HwVlFoS|#EXXiNf)<Dl7e0Yi3P<95~0Q{D%_VHjT3dQ1X-!co{%=S`#pzA7a6Xi&_(1ymi&)-H+%cMpU` zfZ%Qm5AN>n?(R--C%8j!cXx*nJVN)2(tE!-*M~G~FybrnwLx*C`>(bW>2RAYNn$W&61V@sNV(RzqUJGv@QVBHLy<4@* z3$lxW+~qfdUjiySy%8+>rFPl*O%SpBX3i47W&_3yaY0xZO#~)wqlJ2&Ia}u&QvbF= zK`d3JxI?ZM#qg#m-DiNM*ul2b<3cYhF4F!TkDwy$ht7pIe^#ttBV6)7_b_~~gBIKh zEpzHRVx{S1R%sL2H#JH6G!&PEQv-2p{17={>MeUEXY8Pjd>NZk>59hqouBSSC@G<; z3F4e9L1Qx2fw0Oa@YL=BUg`3p)3pct^?p{mR^#1YNA?euJ6rUayBnzNPQy<@7zPZ&Oy4@MfSIpN(Bil%w3Ruq)nRq3e!~eLP$-dGT2j;6sa)JH=hvDE|D=AZdKB>} zEJP&q2&NVLkwMDlcy%y;*`_mI%F0hI={eEz=qDjLHdAga40=0sa6R%q+NS~j1jX8# z_tvASRvfi{Xcn5nyt+0eYM;Nv*SEqP+r8gMWHTpDr~lbcB?-^f0o0Z)56I|`p%En{ zURDSayl9a*F3M5R9*VNRJjJ-WPmGJnAaYzY4Gs*#-_kZ`E!275q%W1>N1}Z9YnKbg z+c3*s$5;|>2CFfGL;h+T#>JCG)qVg|k4s?H51!-ed1bCu5>^gbHyT;)3ydy2A)vFH zduh8JPW!^en~Kd!eX>@pEbS4vNI#TS*m!Zo>(YUAi6MH!&%s-44_%KXu8*ANBrQyr+MH!80?8m8lqnf8ez2N z8#nwHC*1OG6ZF|@0&-FKN9rLmFuKH11(hU6RsIo5C5WXEdh4Y4l8R%OuP)cIQi46( zJqBlZ8>t+~q=;`N+^D-?3n7uWMdnxNDA3K`Fv^z|?@=8SLVZoWPOt2`Xf>24WaeZ6 zI)&kTf5Y2v^Uj$4NOb*(juq1kT@V(AB(6T%FmkKG z)ifJM>f@JOg-+qpG^LVzfZUmo7mQ(=PAdYYa5N`n2@q0S`=7- z98(Ne%Iq|XD5i2KUqn~1zu(KTMv0f1)p~PUZK_N{H{9ys(^pEW=#2D zF0m$FubRoSapr!aZu#|l(2~UzzUwA?+pMFez#h{iFIH(K#OG__z>N;crgtC@Kv5Jn zt{BOox~A%(=NdRcAFoEl)#ZA`o@7-)Pv`(9g~sg;-7ZRo1GQDjA3_W#bzj!OP( z%C<;4KzbwtCan~n%KO)GD1~z!YR{>a@23eGPpjQuyC%SNuXlASc{{7UhbICna)+(L zMl+ua$QzhPmT0lpwsf+_2b&jnZ&7S)X!HDr)783w7Edk9R@6yM`SR8>b-zxxJM<6J zAYy^n68lJ6$Ok&!g&K3rC69SttXsulNGA6?eF27|>oQ8gpI{@e&H=`gOdo9e*UsOy zc6%ao_lyq))OsaKBi|y-=SN+gZ)8W*1#_rqP`gBKVMFpw2 zyiRp7w==dt+MFDSc;vp|@+HdfOq0X9^13luM!|eB-qd3?6!h4GJ8vIMGBm2 z#3S^as-8A4!505fHUi&>q&)vN?RvXFpRhvYD&X?a`Tlw)H8Uo+y~-fX><}PM{2)o* za50f)JVKku^49ik8=+y9d%pK-K88@$Wnsga_{RRwfZE4jxthVmWu>V{s_CB6IAlE1 zrtQ7XK|HY@v}%R~)ojrj`sd9hvlCxOM-FFQrz$-SOu5x&>iqgJ zRu!K309L+BWWd$enX*9C`(WO}Qs3i>pjZ~$2!fp!&?kl&HTzVWlL znSFGNHQkbf2~*YwA1xtZ z3R}u1M%WDZBWt9v*n~m_d@7FRP=1A&0LcXTY|P%!OB5Zwz%hUc=@oh)A;BBl7&$sQ z80%XjfzE6VERfh)01N=o2{$*rnyi6^v7r;_Ox&6gz|IW1puo#ZFXv!usA%k@NiQcP z0=lAaYAm2lFYM+ds_3NeWDL4nRFM(D2>kPQUfzF|%=)jAMJVJP%w0fta{@r6895s| zncLa`RK?{u`RyEx9UVEDfy^AblD1A}&JO0Bf?^Czzf(*Ym>8JpoXkxq>6P5=jOj(p zt&AP*j1B+x47PtggNcp-R2M~a4`WRhAOnDffkB&I1i=1U357qh%gTw<(zjx6jPbc~>(Y})j)F2)Xa4(2va026&HM`L;= zeN#tGW(HOYevk-_0di)xPPUF_wsrt^ItEH@dT|>|M@@QbTN_(LGY4C1V+sK)eM3u1 z#@8!`R?bGoM!%&f@2qcS?&J<&dLb!e8&fAU06XyYy`79f1`;cf1ci(Z zZH+)xc$LSW4Mr~@VC$wy%RtA>#sQ#Zq~l=Z05H-48QDQc78Yi0dIe)gTW1GDV@JU6 z)>fcbbT)AMEl^trYkCpT;k7sbBfYe~lY_aNCL^d041nK9(96q-1K3~148p>n(18~V zquORw8dh3oon&TUsIRV|GfpKYl9F93nc_zOZH`~yJHc?He?8!fLu6ESx)Hu?{cCTHtt z{@OP*IoRpgU(v@3U||A13UtN@1pJlA#==0y#KFM<1Ok}Z7=GW%$OQQ3)V~V&0|{2n zzn{R!{2THNpnQLwYSaII>)+^l?f0O*`A3(3O#$HosQq`ag1Xs%6X~B|!{vbF+Z_O$ix{ump30p{066`Esf7`sEQgC zRZP{0;L?gd_$HO<2?7zUTM85VpRfyj?KpposDidOPR2G)j(|T#$3J?l9B2fkm(zCu zT>vn${q9-x3bwCfDS&}q+Stfk|Ft{6iuOvbj;0O+5Ul?lMk$f8ZJbHV*DS9Y{w`%8(;wpcZ==ue-+xqH z1XOiUClLWbo8^x>im-ry@_Ur0S5kTf&FjpeKrg}uy5o1Rq!$6Dvi#9-BFv!EKW|_J z^&i%MoK2LB-JJfT&ih+_e^l&Gq%m=@GW`SA{ys*1R{atGV-T&v3+yHL66T8#EY4;U z`=ZX6g1Clzat&3(G$bsdxEKHoV_o6sG3s)GDRmlGC_0493(+0n={@b~=w~iX$^Tp=V{b8_|=M$a^g!RC=pm8Ws zfZdMJf|LGOm>}CwQh8VLxFb$pVuIV+`TDok#*PK?^0i7EA5Z6N|4QG&qjVg;&X&9% zw=Sq0CD*;kf|gH*18*N@?pdSHX3-X~M8JvapT!?gp^p3K@NWb?!iaRYPE2X|685Gw zTOYO+YQzkOip+L6!R>Sh!V>mv=QdR~iqX!vkz*m{Wi9eg_4{x;;FjOsAZiL^-~;8E z76Xwap-u~HobI$|5IR`FQy3^OS)$$(q`-TP~c_jU%#ziLBQTwfWLBUc_EE zp8TmDQvMb{RE)E%M@x^1iWjG^8ON;Yoej#+oqilDd#5VTvM1ZJ7gd%E&r>Rvuo<(l zINyHNxeuLaY7PDt5H7N7iU;%;m7IXfGa4vqsXHtzYHz_2(rxJ=~}YGyhkb%F@gaV0_fPoSUb`ur~a(`=n6+C^>P+}C9rkf;pdRti|54B z+E!EFg-p(}(l>8=ND$H0JF|BSDDa$O-`gTvD@L@Q?$5#rS14+S8eYqN=UNKe1$ba= zKu!k)U7=LSDV>p_oXMU8$`GKmLaX{^FFW#9{cS@lzs+srlxNoZQVHN*652A{6m=jf zq5!Kl;)4MSsCP2>!g1&@%1oV@T-w~G$38|vc{N^L9I$!66y_gfJw(+~R&Z!nX3aq+xS5W3bFq#KIc2Ob8orci*n%PGIDNN7Q4Ae>8CEm2o_nM6e(wLDMzJ<<6=J( z3Zp}10pnoeE$Ne3LOYo6feVN0M=8Hrxe!!fT^SByo1> zv*dF4inRp|;W$`zTW6hll!TE^30t=7Mtp^*Ua_{=p z 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

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 0000000000000000000000000000000000000000..abf719555218609f1b14c2d61437975ba2132ef7 GIT binary patch literal 10586 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e0900e959896550f800f86f36d66cf4343d15371 GIT binary patch literal 38798 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 C4Ryc( literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..87ea33617c8863d6ef9f80bccca058d811787f48 GIT binary patch literal 47561 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 + + + + 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 0000000000000000000000000000000000000000..519678fafe601150c2e42fba9aedbe653182e523 GIT binary patch literal 7120 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 Dec*VM literal 0 HcmV?d00001 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

+
+
    +
  • +

    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 0000000000000000000000000000000000000000..eb05578c9cfdaa2922c84ed5a103adba6abd1696 GIT binary patch literal 509952 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

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.
+

0Q@;^u5UH^DI(d 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 literal 0 HcmV?d00001 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)