├── .classpath
├── .github
├── dependabot.yml
└── workflows
│ ├── codeql-analysis.yml
│ └── sonarcloud.yml
├── .gitignore
├── .project
├── .settings
├── edu.umd.cs.findbugs.core.prefs
├── org.eclipse.core.resources.prefs
├── org.eclipse.jdt.apt.core.prefs
├── org.eclipse.jdt.core.prefs
├── org.eclipse.jdt.ui.prefs
├── org.eclipse.m2e.core.prefs
├── org.eclipse.wst.common.component
├── org.eclipse.wst.common.project.facet.core.xml
└── org.eclipse.wst.validation.prefs
├── AUTHORS
├── ClassHierarchy.png
├── ClassHierarchy2.png
├── LICENSE
├── README.md
├── pom.xml
├── postgis-java-ng dependencies.launch
├── postgis-java-ng only release (MacOS).launch
├── postgis-java-ng only release (Windows).launch
├── postgis-java-ng package.launch
├── postgis-java-ng release (MacOS).launch
├── postgis-java-ng release (Windows).launch
└── src
├── main
├── java
│ └── io
│ │ └── github
│ │ └── sebasbaumh
│ │ └── postgis
│ │ ├── CircularString.java
│ │ ├── CompoundCurve.java
│ │ ├── Curve.java
│ │ ├── CurvePolygon.java
│ │ ├── DriverWrapper.java
│ │ ├── Geometry.java
│ │ ├── GeometryCollection.java
│ │ ├── LineBasedGeometry.java
│ │ ├── LineString.java
│ │ ├── LinearRing.java
│ │ ├── MultiCurve.java
│ │ ├── MultiGeometry.java
│ │ ├── MultiLineString.java
│ │ ├── MultiPoint.java
│ │ ├── MultiPolygon.java
│ │ ├── MultiSurface.java
│ │ ├── PGbox2d.java
│ │ ├── PGbox3d.java
│ │ ├── PGboxbase.java
│ │ ├── PGgeography.java
│ │ ├── PGgeometry.java
│ │ ├── PGgeometrybase.java
│ │ ├── Point.java
│ │ ├── Polygon.java
│ │ ├── PolygonBase.java
│ │ ├── PostGisUtil.java
│ │ └── binary
│ │ ├── BinaryParser.java
│ │ ├── BinaryValueGetter.java
│ │ ├── BinaryValueSetter.java
│ │ ├── BinaryWriter.java
│ │ ├── StringValueGetter.java
│ │ ├── StringValueSetter.java
│ │ ├── ValueGetter.java
│ │ ├── ValueSetter.java
│ │ └── package-info.java
└── resources
│ ├── META-INF
│ └── services
│ │ └── java.sql.Driver
│ └── org
│ └── postgresql
│ └── driverconfig.properties
└── test
└── java
└── io
└── github
└── sebasbaumh
└── postgis
├── BoxesTest.java
├── DatabaseTestBase.java
├── DatatypesTest.java
├── DriverWrapperTest.java
├── EmptyGeometriesTest.java
├── GeographyTest.java
├── ParserLocalTest.java
├── ParserTest.java
├── PostgisDatabaseTest.java
├── SerializationTest.java
├── ServerTest.java
├── ServiceTest.java
├── TokenizerTest.java
└── VersionPrinterTest.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "maven" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 | - package-ecosystem: "github-actions"
13 | directory: "/"
14 | schedule:
15 | interval: "weekly"
16 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [master]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [master]
20 | schedule:
21 | - cron: '0 16 * * 0'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'java' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v4
42 |
43 | # setup Java 21 using Eclipse Temurin/Adoptium
44 | - uses: actions/setup-java@v4
45 | with:
46 | java-version: 21
47 | distribution: temurin
48 | cache: maven
49 |
50 | # Initializes the CodeQL tools for scanning.
51 | - name: Initialize CodeQL
52 | uses: github/codeql-action/init@v3
53 | with:
54 | languages: ${{ matrix.language }}
55 | # If you wish to specify custom queries, you can do so here or in a config file.
56 | # By default, queries listed here will override any specified in a config file.
57 | # Prefix the list here with "+" to use these queries and those in the config file.
58 |
59 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
60 | # queries: security-extended,security-and-quality
61 |
62 |
63 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
64 | # If this step fails, then you should remove it and run the build manually (see below)
65 | - name: Autobuild
66 | uses: github/codeql-action/autobuild@v3
67 |
68 | # ℹ️ Command-line programs to run using the OS shell.
69 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
70 |
71 | # If the Autobuild fails above, remove it and uncomment the following three lines.
72 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
73 |
74 | # - run: |
75 | # echo "Run, Build Application using script"
76 | # ./location_of_script_within_repo/buildscript.sh
77 |
78 | - name: Perform CodeQL Analysis
79 | uses: github/codeql-action/analyze@v3
80 |
--------------------------------------------------------------------------------
/.github/workflows/sonarcloud.yml:
--------------------------------------------------------------------------------
1 | name: sonarcloud
2 | on:
3 | push:
4 | branches:
5 | - master
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | with:
12 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
13 | - name: Set up JDK 21
14 | uses: actions/setup-java@v4
15 | with:
16 | java-version: 21
17 | distribution: temurin
18 | cache: maven
19 | - name: Analyze with sonarcloud
20 | run: mvn --batch-mode verify sonar:sonar -Dsonar.projectKey=sebasbaumh_postgis-java-ng -Dsonar.organization=sebasbaumh -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=${{ secrets.SONAR_TOKEN }}
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | # Maven build/release
25 | /target/
26 | *.releaseBackup
27 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | postgis-java-ng
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.common.project.facet.core.builder
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.wst.validation.validationbuilder
25 |
26 |
27 |
28 |
29 | org.eclipse.m2e.core.maven2Builder
30 |
31 |
32 |
33 |
34 |
35 | org.eclipse.jem.workbench.JavaEMFNature
36 | org.eclipse.wst.common.modulecore.ModuleCoreNature
37 | org.eclipse.jdt.core.javanature
38 | org.eclipse.m2e.core.maven2Nature
39 | edu.umd.cs.findbugs.plugin.eclipse.findbugsNature
40 | org.eclipse.wst.common.project.facet.core.nature
41 |
42 |
43 |
44 | 1714375844981
45 |
46 | 30
47 |
48 | org.eclipse.core.resources.regexFilterMatcher
49 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding//src/main/java=UTF-8
3 | encoding//src/main/resources=UTF-8
4 | encoding//src/test/java=UTF-8
5 | encoding//src/test/resources=UTF-8
6 | encoding/=UTF-8
7 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.apt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.apt.aptEnabled=false
3 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | cleanup.add_all=false
2 | cleanup.add_default_serial_version_id=false
3 | cleanup.add_generated_serial_version_id=true
4 | cleanup.add_missing_annotations=true
5 | cleanup.add_missing_deprecated_annotations=true
6 | cleanup.add_missing_methods=true
7 | cleanup.add_missing_nls_tags=false
8 | cleanup.add_missing_override_annotations=true
9 | cleanup.add_missing_override_annotations_interface_methods=true
10 | cleanup.add_serial_version_id=true
11 | cleanup.always_use_blocks=true
12 | cleanup.always_use_parentheses_in_expressions=false
13 | cleanup.always_use_this_for_non_static_field_access=false
14 | cleanup.always_use_this_for_non_static_method_access=false
15 | cleanup.array_with_curly=false
16 | cleanup.arrays_fill=false
17 | cleanup.bitwise_conditional_expression=false
18 | cleanup.boolean_literal=false
19 | cleanup.boolean_value_rather_than_comparison=true
20 | cleanup.break_loop=false
21 | cleanup.collection_cloning=false
22 | cleanup.comparing_on_criteria=false
23 | cleanup.comparison_statement=false
24 | cleanup.controlflow_merge=false
25 | cleanup.convert_functional_interfaces=false
26 | cleanup.convert_to_enhanced_for_loop=false
27 | cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
28 | cleanup.convert_to_switch_expressions=false
29 | cleanup.correct_indentation=true
30 | cleanup.do_while_rather_than_while=true
31 | cleanup.double_negation=false
32 | cleanup.else_if=false
33 | cleanup.embedded_if=false
34 | cleanup.evaluate_nullable=false
35 | cleanup.extract_increment=false
36 | cleanup.format_source_code=true
37 | cleanup.format_source_code_changes_only=false
38 | cleanup.hash=false
39 | cleanup.if_condition=false
40 | cleanup.insert_inferred_type_arguments=false
41 | cleanup.instanceof=false
42 | cleanup.instanceof_keyword=false
43 | cleanup.invert_equals=false
44 | cleanup.join=false
45 | cleanup.lazy_logical_operator=true
46 | cleanup.make_local_variable_final=false
47 | cleanup.make_parameters_final=false
48 | cleanup.make_private_fields_final=false
49 | cleanup.make_type_abstract_if_missing_method=false
50 | cleanup.make_variable_declarations_final=true
51 | cleanup.map_cloning=false
52 | cleanup.merge_conditional_blocks=false
53 | cleanup.multi_catch=false
54 | cleanup.never_use_blocks=false
55 | cleanup.never_use_parentheses_in_expressions=true
56 | cleanup.no_string_creation=false
57 | cleanup.no_super=false
58 | cleanup.number_suffix=true
59 | cleanup.objects_equals=false
60 | cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
61 | cleanup.operand_factorization=false
62 | cleanup.organize_imports=true
63 | cleanup.overridden_assignment=false
64 | cleanup.plain_replacement=false
65 | cleanup.precompile_regex=false
66 | cleanup.primitive_comparison=false
67 | cleanup.primitive_parsing=false
68 | cleanup.primitive_rather_than_wrapper=true
69 | cleanup.primitive_serialization=false
70 | cleanup.pull_out_if_from_if_else=false
71 | cleanup.pull_up_assignment=false
72 | cleanup.push_down_negation=false
73 | cleanup.qualify_static_field_accesses_with_declaring_class=false
74 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
75 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
76 | cleanup.qualify_static_member_accesses_with_declaring_class=true
77 | cleanup.qualify_static_method_accesses_with_declaring_class=false
78 | cleanup.reduce_indentation=false
79 | cleanup.redundant_comparator=false
80 | cleanup.redundant_falling_through_block_end=false
81 | cleanup.remove_private_constructors=true
82 | cleanup.remove_redundant_modifiers=true
83 | cleanup.remove_redundant_semicolons=true
84 | cleanup.remove_redundant_type_arguments=false
85 | cleanup.remove_trailing_whitespaces=true
86 | cleanup.remove_trailing_whitespaces_all=true
87 | cleanup.remove_trailing_whitespaces_ignore_empty=false
88 | cleanup.remove_unnecessary_array_creation=true
89 | cleanup.remove_unnecessary_casts=true
90 | cleanup.remove_unnecessary_nls_tags=true
91 | cleanup.remove_unused_imports=true
92 | cleanup.remove_unused_local_variables=true
93 | cleanup.remove_unused_private_fields=true
94 | cleanup.remove_unused_private_members=true
95 | cleanup.remove_unused_private_methods=true
96 | cleanup.remove_unused_private_types=true
97 | cleanup.return_expression=false
98 | cleanup.simplify_lambda_expression_and_method_ref=false
99 | cleanup.single_used_field=false
100 | cleanup.sort_members=true
101 | cleanup.sort_members_all=true
102 | cleanup.standard_comparison=false
103 | cleanup.static_inner_class=false
104 | cleanup.strictly_equal_or_different=false
105 | cleanup.stringbuffer_to_stringbuilder=false
106 | cleanup.stringbuilder=false
107 | cleanup.stringbuilder_for_local_vars=true
108 | cleanup.stringconcat_to_textblock=false
109 | cleanup.substring=false
110 | cleanup.switch=false
111 | cleanup.system_property=false
112 | cleanup.system_property_boolean=false
113 | cleanup.system_property_file_encoding=false
114 | cleanup.system_property_file_separator=false
115 | cleanup.system_property_line_separator=false
116 | cleanup.system_property_path_separator=false
117 | cleanup.ternary_operator=false
118 | cleanup.try_with_resource=false
119 | cleanup.unlooped_while=false
120 | cleanup.unreachable_block=false
121 | cleanup.use_anonymous_class_creation=false
122 | cleanup.use_autoboxing=false
123 | cleanup.use_blocks=false
124 | cleanup.use_blocks_only_for_return_and_throw=false
125 | cleanup.use_directly_map_method=false
126 | cleanup.use_lambda=true
127 | cleanup.use_parentheses_in_expressions=false
128 | cleanup.use_string_is_blank=false
129 | cleanup.use_this_for_non_static_field_access=false
130 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true
131 | cleanup.use_this_for_non_static_method_access=false
132 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true
133 | cleanup.use_unboxing=false
134 | cleanup.use_var=false
135 | cleanup.useless_continue=false
136 | cleanup.useless_return=false
137 | cleanup.valueof_rather_than_instantiation=false
138 | cleanup_profile=_SB
139 | cleanup_settings_version=2
140 | eclipse.preferences.version=1
141 | formatter_profile=_SB
142 | formatter_settings_version=23
143 | org.eclipse.jdt.ui.text.custom_code_templates=
144 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.component:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.project.facet.core.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.validation.prefs:
--------------------------------------------------------------------------------
1 | disabled=06target
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | (C) 2004 Paul Ramsey, pramsey@refractions.net
2 | (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
3 | (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
4 | (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
5 |
--------------------------------------------------------------------------------
/ClassHierarchy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sebasbaumh/postgis-java-ng/0257200c3424e4129ee9de57b54c4dff5a7c001c/ClassHierarchy.png
--------------------------------------------------------------------------------
/ClassHierarchy2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sebasbaumh/postgis-java-ng/0257200c3424e4129ee9de57b54c4dff5a7c001c/ClassHierarchy2.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PostGIS Java bindings (Next Generation) #
2 |
3 | [](https://github.com/sebasbaumh/postgis-java-ng/actions/workflows/codeql-analysis.yml)
4 | [](https://search.maven.org/artifact/io.github.sebasbaumh/postgis-java-ng)
5 | [](https://javadoc.io/doc/io.github.sebasbaumh/postgis-java-ng/latest/index.html)
6 | [](https://github.com/sebasbaumh/postgis-java-ng/blob/master/LICENSE)
7 |
8 | [](https://sonarcloud.io/dashboard?id=sebasbaumh_postgis-java-ng)
9 | [](https://sonarcloud.io/dashboard?id=sebasbaumh_postgis-java-ng)
10 | [](https://sonarcloud.io/dashboard?id=sebasbaumh_postgis-java-ng)
11 | [](https://sonarcloud.io/dashboard?id=sebasbaumh_postgis-java-ng)
12 |
13 | This project contains Java bindings for using [PostGIS](https://postgis.net/) geometries coming from a [PostgreSQL](https://www.postgresql.org/) database.
14 | *It is originally based on [postgis-java](https://github.com/postgis/postgis-java) and I want to thank its authors for their work.*
15 |
16 | **Project goals and improvements:**
17 | * Support for geometries containing arcs like `CIRCULARSTRING` or `CURVEPOLYGON`
18 | * Support for PostGIS [geography datatype](https://postgis.net/docs/using_postgis_dbmanagement.html#PostGIS_Geography)
19 | * Extended support for bounding boxes, i.e. [box2d](https://postgis.net/docs/box2d_type.html)/[box3d](https://postgis.net/docs/box3d_type.html) PostGIS data types (as PGbox2d/PGbox3d)
20 | * Support for wrapped connections (like used in WildFly and c3p0 connection pooling)
21 | * Use generic Java types where possible and simplify/streamline API
22 | * Clean up code to basically only work on [WKB](https://en.wikipedia.org/wiki/Well-known_text#Well-known_binary)/EWKB implementations to reduce code duplication and focus on the actual database format
23 | * Support for binary transfer of geometry data (if enabled in PostgreSQL JDBC driver)
24 | * use PostgreSQL JDBC driver [42.5.1](https://jdbc.postgresql.org/changelogs/2023-01-31-42.5.2-release/) or later to enable it automatically
25 | * Support for the latest PostgreSQL and PostGIS versions
26 | * Recommended are PostgreSQL 15.1 and PostGIS 3.2.2
27 | * Supported are versions starting from PostgreSQL 9.6 and PostGIS 2.3
28 | * Support for current JDKs
29 | * JDK 21 ([main branch](https://github.com/sebasbaumh/postgis-java-ng/tree/master))
30 | * deprecated branches
31 | * [JDK 17](https://github.com/sebasbaumh/postgis-java-ng/tree/jdk17)
32 | * [JDK 11](https://github.com/sebasbaumh/postgis-java-ng/tree/jdk11)
33 | * [JDK 8](https://github.com/sebasbaumh/postgis-java-ng/tree/jdk8)
34 | * The [license](https://github.com/sebasbaumh/postgis-java-ng/blob/master/LICENSE) is still LGPL
35 | * The authors are listed [here](https://github.com/sebasbaumh/postgis-java-ng/blob/master/AUTHORS)
36 |
37 | **Supported [geometry types](https://postgis.net/docs/using_postgis_dbmanagement.html#RefObject):**
38 | * `Point`
39 | * `LineString`
40 | * `CircularString`
41 | * `CompoundCurve`
42 | * `Polygon`
43 | * `CurvePolygon`
44 | * `MultiPoint`
45 | * `MultiLineString`
46 | * `MultiCurve`
47 | * `MultiPolygon`
48 | * `MultiSurface`
49 | * `GeometryCollection`
50 | * `box2d`
51 | * `box3d`
52 |
53 | ## How to use it ##
54 | There is a Maven artifact in the official Maven repository, so just add this to your Maven POM:
55 |
56 | ```xml
57 |
58 | io.github.sebasbaumh
59 | postgis-java-ng
60 | 25.1.0
61 |
62 | ```
63 |
64 | The version reflects the year of the release, e.g. `25.1.0` is a version released in 2024.
65 |
66 | The API differs a bit from [postgis-java](https://github.com/postgis/postgis-java) with the main point being a different namespace (`io.github.sebasbaumh.postgis`) as publishing a project to Maven Central requires to own that namespace.
67 | In addition the class structure is a bit different (see below) to support arc geometries and reduce boilerplate code, but you should be able to adapt to it easily.
68 | The implementations of the parser and writer for the geometries have been heavily reworked to speed up processing and reduce complexity.
69 |
70 | ## Hierarchy of geometry classes: ##
71 |
72 | 
73 |
74 | 
75 |
76 | ## How to run tests utilizing a PostgreSQL server ##
77 |
78 | You will need a PostgreSQL server with installed PostGIS extension for some of the tests.
79 |
80 | In this example the server is named `MyServer` and the database `UnitTestDB`. The database can be empty except installing the PostGIS extension.
81 |
82 | You should set up a database user for the unit tests, which has access rights to this database and only to this one.
83 | In this example the user is called `unittest` and has the password `CHANGEME`.
84 |
85 | To run the unit tests accessing the server, add the following to your VM arguments (eclipse Run Configuration->Arguments->VM arguments):
86 |
87 | `-DtestJdbcUrl="jdbc:postgresql://MyServer/UnitTestDB" -DtestJdbcUsername="unittest" -DtestJdbcPassword="CHANGEME"`
88 |
89 | Or add the following Maven build parameters to the launch configuration in eclipse:
90 |
91 | |Parameter Name|Value|
92 | |--------------|-----|
93 | |`testJdbcUrl`|`jdbc:postgresql://MyServer/UnitTestDB`|
94 | |`testJdbcUsername`|`unittest`|
95 | |`testJdbcPassword`|`CHANGEME`|
96 |
97 | If it works, you will see this line in the build output:
98 |
99 | ```
100 | Tests are running with a database
101 | ```
102 |
103 | else
104 |
105 | ```
106 | Tests are running without a database
107 | ```
108 |
109 | *There are also local tests contained in the project, so you are still able to test most parts without specifying a PostgreSQL server. And the test console output will show if tests were run with or without a database.*
110 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | io.github.sebasbaumh
5 | postgis-java-ng
6 |
7 | 25.1.1-SNAPSHOT
8 | jar
9 |
10 | PostGIS Java bindings
11 | This project contains Java bindings for using PostGIS geometries coming from a PostgreSQL database.
12 | https://github.com/sebasbaumh/postgis-java-ng
13 |
14 |
15 |
16 | GNU Lesser General Public License v3.0
17 | https://www.gnu.org/licenses/lgpl-3.0.en.html
18 |
19 |
20 |
21 |
22 |
23 | Sebastian Baumhekel
24 | sebastian.baumhekel@gmail.com
25 | https://github.com/sebasbaumh
26 |
27 |
28 |
29 |
30 | scm:git:git://github.com/sebasbaumh/postgis-java-ng.git
31 | scm:git:ssh://github.com:sebasbaumh/postgis-java-ng.git
32 | https://github.com/sebasbaumh/postgis-java-ng/tree/master
33 | v25.1.0
34 |
35 |
36 |
37 |
38 | ossrh
39 | https://s01.oss.sonatype.org/content/repositories/snapshots
40 |
41 |
42 | ossrh
43 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
44 |
45 |
46 |
47 |
48 |
49 | UTF-8
50 |
51 |
52 |
53 |
54 |
55 | com.github.spotbugs
56 | spotbugs-annotations
57 | 4.9.3
58 | provided
59 |
60 |
61 | org.eclipse.jdt
62 | org.eclipse.jdt.annotation
63 | 2.3.100
64 | provided
65 |
66 |
67 |
68 | junit
69 | junit
70 | 4.13.2
71 | test
72 |
73 |
74 | com.mchange
75 | c3p0
76 | 0.11.1
77 | test
78 |
79 |
80 | com.mchange
81 | mchange-commons-java
82 | 0.3.2
83 | test
84 |
85 |
86 | org.slf4j
87 | slf4j-api
88 | 2.0.17
89 | test
90 |
91 |
92 | org.slf4j
93 | slf4j-jdk14
94 | 2.0.17
95 | test
96 |
97 |
98 |
99 | org.postgresql
100 | postgresql
101 | 42.7.6
102 |
103 |
104 |
105 |
106 |
107 |
108 | maven-compiler-plugin
109 | 3.14.0
110 |
111 | 21
112 | 21
113 | -Xlint:all
114 |
115 |
116 |
117 |
118 |
119 | org.apache.maven.plugins
120 | maven-source-plugin
121 | 3.3.1
122 |
123 |
124 | attach-sources
125 |
126 | jar-no-fork
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | org.apache.maven.plugins
135 | maven-javadoc-plugin
136 | 3.11.2
137 |
138 |
139 | attach-javadocs
140 |
141 | jar
142 |
143 |
144 |
145 | 21
146 |
147 | none
148 | false
149 |
150 |
151 |
152 |
153 |
154 | org.apache.maven.plugins
155 | maven-enforcer-plugin
156 | 3.5.0
157 |
158 |
159 | enforce-maven
160 |
161 | enforce
162 |
163 |
164 |
165 |
166 | 3.9
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | org.apache.maven.plugins
176 | maven-deploy-plugin
177 | 3.1.4
178 |
179 |
180 | org.apache.maven.plugins
181 | maven-gpg-plugin
182 | 3.2.7
183 |
184 |
185 |
186 |
187 |
188 |
189 | org.apache.maven.plugins
190 | maven-release-plugin
191 | 3.1.1
192 |
193 | true
194 | false
195 | release-sign-artifacts
196 | v@{project.version}
197 |
198 |
199 |
200 | org.sonatype.central
201 | central-publishing-maven-plugin
202 | 0.7.0
203 | true
204 |
205 | central
206 | true
207 |
208 |
209 |
210 |
211 | org.apache.maven.plugins
212 | maven-dependency-plugin
213 | 3.8.1
214 |
215 |
216 | org.codehaus.mojo
217 | versions-maven-plugin
218 | 2.18.0
219 |
220 |
221 |
222 |
223 |
224 |
230 |
231 | release-sign-artifacts
232 |
233 |
234 |
235 | org.apache.maven.plugins
236 | maven-gpg-plugin
237 |
238 |
239 | sign-artifacts
240 | verify
241 |
242 | sign
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/postgis-java-ng dependencies.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/postgis-java-ng only release (MacOS).launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/postgis-java-ng only release (Windows).launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/postgis-java-ng package.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/postgis-java-ng release (MacOS).launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/postgis-java-ng release (Windows).launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/CircularString.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * The CIRCULARSTRING is the basic curve type, similar to a LINESTRING in the linear world. A single segment required
29 | * three points, the start and end points (first and third) and any other point on the arc. The exception to this is for
30 | * a closed circle, where the start and end points are the same. In this case the second point MUST be the center of the
31 | * arc, ie the opposite side of the circle. To chain arcs together, the last point of the previous arc becomes the first
32 | * point of the next arc, just like in LINESTRING. This means that a valid circular string must have an odd number of
33 | * points greater than 1.
34 | * @author Sebastian Baumhekel
35 | */
36 | @NonNullByDefault
37 | public class CircularString extends LineString
38 | {
39 | /* JDK 1.5 Serialization */
40 | private static final long serialVersionUID = 0x100;
41 | /**
42 | * The OGIS geometry type number for arcs/circles.
43 | */
44 | public static final int TYPE = 8;
45 |
46 | /**
47 | * Constructs an instance.
48 | */
49 | public CircularString()
50 | {
51 | super(TYPE);
52 | }
53 |
54 | /**
55 | * Constructs an instance.
56 | * @param points points
57 | */
58 | public CircularString(Iterable points)
59 | {
60 | super(TYPE);
61 | addAll(points);
62 | }
63 |
64 | /*
65 | * (non-Javadoc)
66 | * @see io.github.sebasbaumh.postgis.LineBasedGeom#length()
67 | */
68 | @Override
69 | public double length()
70 | {
71 | // FIX: calculate length on arc
72 | return super.length();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/CompoundCurve.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collection;
27 | import java.util.Collections;
28 | import java.util.Iterator;
29 |
30 | import javax.annotation.Nullable;
31 |
32 | import org.eclipse.jdt.annotation.NonNullByDefault;
33 |
34 | /**
35 | * A compound curve is a single, continuous curve that has both curved (circular) segments and linear segments. That
36 | * means that in addition to having well-formed components, the end point of every component (except the last) must be
37 | * coincident with the start point of the following component. Just note: here it is treated as a special
38 | * {@link MultiCurve} where the end points of all contained lines match.
39 | * @author Sebastian Baumhekel
40 | */
41 | @NonNullByDefault
42 | public class CompoundCurve extends Curve implements Iterable
43 | {
44 | private static final long serialVersionUID = 0x100;
45 | /**
46 | * The OGIS geometry type number for single, continuous curves that have both curved (circular) segments and linear
47 | * segments.
48 | */
49 | public static final int TYPE = 9;
50 |
51 | /**
52 | * Sub geometries.
53 | */
54 | private final ArrayList subgeoms = new ArrayList();
55 |
56 | /**
57 | * Constructs an instance.
58 | */
59 | public CompoundCurve()
60 | {
61 | super(TYPE);
62 | }
63 |
64 | /**
65 | * Constructs an instance.
66 | * @param geoms geometries
67 | */
68 | public CompoundCurve(Iterable extends LineString> geoms)
69 | {
70 | super(TYPE);
71 | addAll(geoms);
72 | }
73 |
74 | /**
75 | * Adds a geometry.
76 | * @param geom geometry
77 | */
78 | public void add(LineString geom)
79 | {
80 | subgeoms.add(geom);
81 | }
82 |
83 | /**
84 | * Adds all given geometries.
85 | * @param geoms geometries
86 | */
87 | public final void addAll(Iterable extends LineString> geoms)
88 | {
89 | for (LineString geom : geoms)
90 | {
91 | subgeoms.add(geom);
92 | }
93 | }
94 |
95 | @Override
96 | public boolean checkConsistency()
97 | {
98 | if (!super.checkConsistency() || subgeoms.isEmpty())
99 | {
100 | return false;
101 | }
102 | return PostGisUtil.checkConsistency(subgeoms);
103 | }
104 |
105 | /**
106 | * Closes this {@link Curve} if the last coordinate is not already the same as the first coordinate.
107 | */
108 | @Override
109 | public void close()
110 | {
111 | LineString lsFirst = PostGisUtil.firstOrDefault(subgeoms);
112 | LineString lsLast = PostGisUtil.lastOrDefault(subgeoms);
113 | if ((lsFirst != null) && (lsLast != null))
114 | {
115 | Point pFirst = lsFirst.getStartPoint();
116 | Point pLast = lsLast.getEndPoint();
117 | // check if there is a first point and the last point equals the first one
118 | if ((pFirst != null) && (pLast != null) && !pFirst.coordsAreEqual(pLast))
119 | {
120 | // add the first point as closing last point
121 | lsLast.add(pFirst.copy());
122 | }
123 | }
124 | }
125 |
126 | @Override
127 | public boolean equals(@Nullable Object other)
128 | {
129 | // check type and parent
130 | if ((other instanceof CompoundCurve cother) && super.equals(other))
131 | {
132 | return PostGisUtil.equalsIterable(this.subgeoms, cother.subgeoms);
133 | }
134 | return false;
135 | }
136 |
137 | /*
138 | * (non-Javadoc)
139 | * @see io.github.sebasbaumh.postgis.Geometry#getCoordinates()
140 | */
141 | @Override
142 | public Iterable getCoordinates()
143 | {
144 | ArrayList l = new ArrayList();
145 | for (LineString geom : subgeoms)
146 | {
147 | for (Point p : geom.getCoordinates())
148 | {
149 | l.add(p);
150 | }
151 | }
152 | return l;
153 | }
154 |
155 | /*
156 | * (non-Javadoc)
157 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getEndPoint()
158 | */
159 | @Nullable
160 | @Override
161 | public Point getEndPoint()
162 | {
163 | LineString ls = PostGisUtil.lastOrDefault(subgeoms);
164 | if (ls != null)
165 | {
166 | return ls.getEndPoint();
167 | }
168 | return null;
169 | }
170 |
171 | /**
172 | * Gets all geometries.
173 | * @return geometries
174 | */
175 | public Collection getGeometries()
176 | {
177 | return subgeoms;
178 | }
179 |
180 | /*
181 | * (non-Javadoc)
182 | * @see io.github.sebasbaumh.postgis.Geometry#getNumberOfCoordinates()
183 | */
184 | @Override
185 | public int getNumberOfCoordinates()
186 | {
187 | int n = 0;
188 | for (LineString geom : subgeoms)
189 | {
190 | n += geom.getNumberOfCoordinates();
191 | }
192 | return n;
193 | }
194 |
195 | /*
196 | * (non-Javadoc)
197 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getStartPoint()
198 | */
199 | @Nullable
200 | @Override
201 | public Point getStartPoint()
202 | {
203 | LineString ls = PostGisUtil.firstOrDefault(subgeoms);
204 | if (ls != null)
205 | {
206 | return ls.getStartPoint();
207 | }
208 | return null;
209 | }
210 |
211 | @Override
212 | public int hashCode()
213 | {
214 | return 31 * super.hashCode() + subgeoms.hashCode();
215 | }
216 |
217 | /*
218 | * (non-Javadoc)
219 | * @see io.github.sebasbaumh.postgis.Geometry#hasMeasure()
220 | */
221 | @Override
222 | public boolean hasMeasure()
223 | {
224 | for (LineString geom : subgeoms)
225 | {
226 | if (geom.hasMeasure())
227 | {
228 | return true;
229 | }
230 | }
231 | return false;
232 | }
233 |
234 | /*
235 | * (non-Javadoc)
236 | * @see io.github.sebasbaumh.postgis.Geometry#is3d()
237 | */
238 | @Override
239 | public boolean is3d()
240 | {
241 | for (LineString geom : subgeoms)
242 | {
243 | if (geom.is3d())
244 | {
245 | return true;
246 | }
247 | }
248 | return false;
249 | }
250 |
251 | /**
252 | * Checks, if there are no sub-geometries.
253 | * @return true on success, else false
254 | */
255 | @Override
256 | public boolean isEmpty()
257 | {
258 | return subgeoms.isEmpty();
259 | }
260 |
261 | /*
262 | * (non-Javadoc)
263 | * @see java.lang.Iterable#iterator()
264 | */
265 | @Override
266 | public Iterator iterator()
267 | {
268 | return subgeoms.iterator();
269 | }
270 |
271 | /*
272 | * (non-Javadoc)
273 | * @see io.github.sebasbaumh.postgis.LineBasedGeom#length()
274 | */
275 | @Override
276 | public double length()
277 | {
278 | double d = 0;
279 | for (LineString ls : subgeoms)
280 | {
281 | d += ls.length();
282 | }
283 | return d;
284 | }
285 |
286 | /*
287 | * (non-Javadoc)
288 | * @see io.github.sebasbaumh.postgis.Curve#reverse()
289 | */
290 | @Override
291 | public void reverse()
292 | {
293 | // reverse linestrings as a whole
294 | Collections.reverse(subgeoms);
295 | // then reverse all individually
296 | for (LineString ls : subgeoms)
297 | {
298 | ls.reverse();
299 | }
300 | }
301 |
302 | @Override
303 | public void setSrid(int srid)
304 | {
305 | super.setSrid(srid);
306 | for (LineString geom : subgeoms)
307 | {
308 | geom.setSrid(srid);
309 | }
310 | }
311 |
312 | /**
313 | * Gets the number of contained geometries.
314 | * @return number of contained geometries
315 | */
316 | public int size()
317 | {
318 | return this.subgeoms.size();
319 | }
320 |
321 | }
322 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/Curve.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * Base class for simple curves like {@link LineString}s and complex classes like {@link CompoundCurve}s.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public abstract class Curve extends Geometry implements LineBasedGeometry
33 | {
34 | private static final long serialVersionUID = 0x100;
35 |
36 | /**
37 | * Constructor for subclasses.
38 | * @param type has to be given by all subclasses
39 | */
40 | protected Curve(int type)
41 | {
42 | super(type);
43 | }
44 |
45 | /**
46 | * Closes this {@link Curve} if the last coordinate is not already the same as the first coordinate.
47 | */
48 | public abstract void close();
49 |
50 | /**
51 | * Checks if this ring is oriented in clockwise direction.
52 | * @return true on success, else false
53 | */
54 | public boolean isClockwise()
55 | {
56 | return isClosed() && (PostGisUtil.calcAreaSigned(getCoordinates()) < 0);
57 | }
58 |
59 | /*
60 | * (non-Javadoc)
61 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#isClosed()
62 | */
63 | @Override
64 | public boolean isClosed()
65 | {
66 | Point pFirst = getStartPoint();
67 | Point pLast = getEndPoint();
68 | return (pFirst != null) && (pLast != null) && pFirst.coordsAreEqual(pLast);
69 | }
70 |
71 | /**
72 | * Reverses this linestring.
73 | */
74 | public abstract void reverse();
75 |
76 | /*
77 | * (non-Javadoc)
78 | * @see java.lang.Object#toString()
79 | */
80 | @Override
81 | public String toString()
82 | {
83 | return this.getClass().getSimpleName() + " [" + this.getNumberOfCoordinates() + " points]";
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/CurvePolygon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * A CURVEPOLYGON is just like a polygon, with an outer ring and zero or more inner rings. The difference is that a ring
29 | * can take the form of a circular string, linear string or compound string.
30 | * @author Sebastian Baumhekel
31 | */
32 | @NonNullByDefault
33 | public class CurvePolygon extends PolygonBase
34 | {
35 | /* JDK 1.5 Serialization */
36 | private static final long serialVersionUID = 0x100;
37 | /**
38 | * The OGIS geometry type number for polygons with curved segments.
39 | */
40 | public static final int TYPE = 10;
41 |
42 | /**
43 | * Constructs an instance.
44 | */
45 | public CurvePolygon()
46 | {
47 | super(TYPE, LineString.class);
48 | }
49 |
50 | /**
51 | * Constructs an instance.
52 | * @param lsOuterRing outer ring
53 | */
54 | public CurvePolygon(Curve lsOuterRing)
55 | {
56 | super(TYPE, lsOuterRing);
57 | }
58 |
59 | /**
60 | * Constructs an instance.
61 | * @param rings rings (first one will be the outer ring)
62 | */
63 | public CurvePolygon(Iterable extends Curve> rings)
64 | {
65 | super(TYPE, LineString.class, rings);
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/Geometry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.io.Serializable;
26 |
27 | import javax.annotation.Nullable;
28 |
29 | import org.eclipse.jdt.annotation.NonNullByDefault;
30 |
31 | /**
32 | * The base class of all geometries
33 | */
34 | @NonNullByDefault
35 | public abstract class Geometry implements Serializable
36 | {
37 | private static final long serialVersionUID = 0x100;
38 |
39 | /**
40 | * Official UNKNOWN srid value
41 | */
42 | public static final int UNKNOWN_SRID = 0;
43 |
44 | /**
45 | * The spacial reference system id of this geometry, default is no srid
46 | */
47 | private int srid = UNKNOWN_SRID;
48 |
49 | /**
50 | * The OGIS geometry type of this feature. this is final as it never changes, it is bound to the subclass of the
51 | * instance.
52 | */
53 | private final int type;
54 |
55 | // WKB types:
56 | // POINT 1
57 | // LINESTRING 2
58 | // POLYGON 3
59 | // MULTIPOINT 4
60 | // MULTILINESTRING 5
61 | // MULTIPOLYGON 6
62 | // GEOMETRYCOLLECTION 7
63 | // CIRCULARSTRING 8
64 | // COMPOUNDCURVE 9
65 | // CURVEPOLYGON 10
66 | // MULTICURVE 11
67 | // MULTISURFACE 12
68 | // CURVE 13
69 | // SURFACE 14
70 | // POLYHEDRALSURFACE 15
71 | // TIN 16
72 | // TRIANGLE 17
73 |
74 | /**
75 | * Constructor for subclasses.
76 | * @param type has to be given by all subclasses
77 | */
78 | protected Geometry(int type)
79 | {
80 | this.type = type;
81 | }
82 |
83 | /**
84 | * Do some internal consistency checks on the geometry. Currently, all Geometries must have a valid dimension (2 or
85 | * 3) and a valid type. Composed geometries must have all equal SRID, dimensionality and measures, as well as that
86 | * they do not contain NULL or inconsistent subgeometries. BinaryParser and WKTParser should only generate
87 | * consistent geometries. BinaryWriter may produce invalid results on inconsistent geometries.
88 | * @return true if all checks are passed.
89 | */
90 | @SuppressWarnings("static-method")
91 | public boolean checkConsistency()
92 | {
93 | // default is a correct geometry
94 | return true;
95 | }
96 |
97 | /**
98 | * java.lang.Object equals implementation
99 | * @param obj geometry to compare
100 | * @return true if equal, false otherwise
101 | */
102 | @Override
103 | public boolean equals(@Nullable Object obj)
104 | {
105 | // short cut
106 | if (this == obj)
107 | {
108 | return true;
109 | }
110 | // check for type and null
111 | if (!(obj instanceof Geometry))
112 | {
113 | return false;
114 | }
115 | // check all properties specific to this instance, rest is checked by subclasses
116 | Geometry other = (Geometry) obj;
117 | return (this.type == other.type) && (this.srid == other.srid);
118 | }
119 |
120 | /**
121 | * Gets the coordinates of this {@link Geometry}.
122 | * @return coordinates
123 | */
124 | public abstract Iterable getCoordinates();
125 |
126 | /**
127 | * Gets the number of coordinates of this {@link Geometry}.
128 | * @return number of coordinates
129 | */
130 | public abstract int getNumberOfCoordinates();
131 |
132 | /**
133 | * The OGIS geometry type number of this geometry.
134 | * @return the SRID of this geometry
135 | */
136 | public int getSrid()
137 | {
138 | return this.srid;
139 | }
140 |
141 | /**
142 | * Gets the OGIS geometry type number of this geometry.
143 | * @return type of this geometry
144 | */
145 | public int getType()
146 | {
147 | return this.type;
148 | }
149 |
150 | /*
151 | * (non-Javadoc)
152 | * @see java.lang.Object#hashCode()
153 | */
154 | @Override
155 | public int hashCode()
156 | {
157 | return 31 * (31 + this.srid) + this.type;
158 | }
159 |
160 | /**
161 | * Returns whether we have a measure (4th dimension)
162 | * @return true if the geometry has a measure, false otherwise
163 | */
164 | public abstract boolean hasMeasure();
165 |
166 | /**
167 | * Checks if this {@link Geometry} is 3d.
168 | * @return true on success, else false
169 | */
170 | public abstract boolean is3d();
171 |
172 | /**
173 | * Ist this {@link Geometry} empty, so does it contain no coordinates or other geometries?
174 | * @return true on success, else false
175 | */
176 | public abstract boolean isEmpty();
177 |
178 | /**
179 | * Recursively sets the srid on this geometry and all contained subgeometries
180 | * @param srid the SRID for this geometry
181 | */
182 | public void setSrid(int srid)
183 | {
184 | this.srid = srid;
185 | }
186 |
187 | }
188 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/GeometryCollection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * Geometry Collection.
29 | * @author markus.schaber@logix-tt.com
30 | */
31 | @NonNullByDefault
32 | public class GeometryCollection extends MultiGeometry
33 | {
34 | /* JDK 1.5 Serialization */
35 | private static final long serialVersionUID = 0x100;
36 | /**
37 | * The OGIS geometry type number for feature collections.
38 | */
39 | public static final int TYPE = 7;
40 |
41 | /**
42 | * Constructs an instance.
43 | */
44 | public GeometryCollection()
45 | {
46 | super(TYPE);
47 | }
48 |
49 | /**
50 | * Constructs an instance.
51 | * @param geoms geometries
52 | */
53 | public GeometryCollection(Iterable geoms)
54 | {
55 | super(TYPE, geoms);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/LineBasedGeometry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import javax.annotation.Nullable;
26 |
27 | /**
28 | * Interface to mark line based geometries.
29 | * @author Sebastian Baumhekel
30 | */
31 | public interface LineBasedGeometry
32 | {
33 | /**
34 | * Gets the end point.
35 | * @return {@link Point} on success, else null
36 | */
37 | @Nullable
38 | Point getEndPoint();
39 |
40 | /**
41 | * Gets the start point.
42 | * @return {@link Point} on success, else null
43 | */
44 | @Nullable
45 | Point getStartPoint();
46 |
47 | /**
48 | * Checks if this line is closed, so the last coordinate is the same as the first coordinate.
49 | * @return true on success, else false
50 | */
51 | boolean isClosed();
52 |
53 | /**
54 | * Gets the length of this line.
55 | * @return length
56 | */
57 | double length();
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/LineString.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collections;
27 | import java.util.Iterator;
28 |
29 | import javax.annotation.Nullable;
30 |
31 | import org.eclipse.jdt.annotation.NonNullByDefault;
32 |
33 | /**
34 | * Linestring.
35 | * @author Sebastian Baumhekel
36 | */
37 | @NonNullByDefault
38 | public class LineString extends Curve implements Iterable
39 | {
40 | /* JDK 1.5 Serialization */
41 | private static final long serialVersionUID = 0x100;
42 |
43 | /**
44 | * The OGIS geometry type number for lines.
45 | */
46 | public static final int TYPE = 2;
47 |
48 | private final ArrayList points = new ArrayList();
49 |
50 | /**
51 | * Constructs an instance.
52 | */
53 | public LineString()
54 | {
55 | super(TYPE);
56 | }
57 |
58 | /**
59 | * Constructor for subclasses.
60 | * @param type has to be given by all subclasses.
61 | */
62 | protected LineString(int type)
63 | {
64 | super(type);
65 | }
66 |
67 | /**
68 | * Constructor for subclasses.
69 | * @param type has to be given by all subclasses.
70 | * @param points {@link Point}s
71 | */
72 | protected LineString(int type, Iterable points)
73 | {
74 | super(type);
75 | addAll(points);
76 | }
77 |
78 | /**
79 | * Constructs an instance.
80 | * @param points points
81 | */
82 | public LineString(Iterable points)
83 | {
84 | super(LineString.TYPE);
85 | addAll(points);
86 | }
87 |
88 | /**
89 | * Adds the given point.
90 | * @param p point
91 | */
92 | public void add(Point p)
93 | {
94 | points.add(p);
95 | }
96 |
97 | /**
98 | * Adds all given points.
99 | * @param geoms points
100 | */
101 | public final void addAll(Iterable geoms)
102 | {
103 | for (Point geom : geoms)
104 | {
105 | points.add(geom);
106 | }
107 | }
108 |
109 | @Override
110 | public boolean checkConsistency()
111 | {
112 | if (!super.checkConsistency() || points.isEmpty())
113 | {
114 | return false;
115 | }
116 | return PostGisUtil.checkConsistency(points);
117 | }
118 |
119 | /**
120 | * Closes this {@link LineString} if the last coordinate is not already the same as the first coordinate.
121 | */
122 | @Override
123 | public void close()
124 | {
125 | Point pFirst = getStartPoint();
126 | Point pLast = getEndPoint();
127 | // check if there is a first point and the last point equals the first one
128 | if ((pFirst != null) && (pLast != null) && !pFirst.coordsAreEqual(pLast))
129 | {
130 | // add the first point as closing last point
131 | add(pFirst.copy());
132 | }
133 | }
134 |
135 | @Override
136 | public boolean equals(@Nullable Object other)
137 | {
138 | // check type and parent
139 | if ((other instanceof LineString ls) && super.equals(other))
140 | {
141 | // check all points
142 | return PostGisUtil.equalsIterable(this.points, ls.points);
143 | }
144 | return false;
145 | }
146 |
147 | /*
148 | * (non-Javadoc)
149 | * @see io.github.sebasbaumh.postgis.Geometry#getCoordinates()
150 | */
151 | @Override
152 | public Iterable getCoordinates()
153 | {
154 | return this.points;
155 | }
156 |
157 | /*
158 | * (non-Javadoc)
159 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getEndPoint()
160 | */
161 | @Nullable
162 | @Override
163 | public Point getEndPoint()
164 | {
165 | return PostGisUtil.lastOrDefault(points);
166 | }
167 |
168 | /*
169 | * (non-Javadoc)
170 | * @see io.github.sebasbaumh.postgis.Geometry#getNumberOfCoordinates()
171 | */
172 | @Override
173 | public int getNumberOfCoordinates()
174 | {
175 | return this.points.size();
176 | }
177 |
178 | /*
179 | * (non-Javadoc)
180 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getStartPoint()
181 | */
182 | @Nullable
183 | @Override
184 | public Point getStartPoint()
185 | {
186 | return PostGisUtil.firstOrDefault(points);
187 | }
188 |
189 | @Override
190 | public int hashCode()
191 | {
192 | return 31 * super.hashCode() + points.hashCode();
193 | }
194 |
195 | /*
196 | * (non-Javadoc)
197 | * @see io.github.sebasbaumh.postgis.Geometry#hasMeasure()
198 | */
199 | @Override
200 | public boolean hasMeasure()
201 | {
202 | for (Point geom : points)
203 | {
204 | if (geom.hasMeasure())
205 | {
206 | return true;
207 | }
208 | }
209 | return false;
210 | }
211 |
212 | /*
213 | * (non-Javadoc)
214 | * @see io.github.sebasbaumh.postgis.Geometry#is3d()
215 | */
216 | @Override
217 | public boolean is3d()
218 | {
219 | for (Point geom : points)
220 | {
221 | if (geom.is3d())
222 | {
223 | return true;
224 | }
225 | }
226 | return false;
227 | }
228 |
229 | /*
230 | * (non-Javadoc)
231 | * @see io.github.sebasbaumh.postgis.Geometry#isEmpty()
232 | */
233 | @Override
234 | public boolean isEmpty()
235 | {
236 | return this.points.isEmpty();
237 | }
238 |
239 | /*
240 | * (non-Javadoc)
241 | * @see java.lang.Iterable#iterator()
242 | */
243 | @Override
244 | public Iterator iterator()
245 | {
246 | return this.points.iterator();
247 | }
248 |
249 | @Override
250 | public double length()
251 | {
252 | double len = 0;
253 | if (points.size() > 1)
254 | {
255 | Point p0 = points.get(0);
256 | for (int i = 1; i < points.size(); i++)
257 | {
258 | Point p = points.get(i);
259 | len += p0.distance(p);
260 | p0 = p;
261 | }
262 | }
263 | return len;
264 | }
265 |
266 | /**
267 | * Reverses this linestring.
268 | */
269 | @Override
270 | public void reverse()
271 | {
272 | Collections.reverse(this.points);
273 | }
274 |
275 | }
276 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/LinearRing.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * This represents the LinearRing GIS datatype. This type is used to construct the polygon types, but is not stored or
29 | * retrieved directly from the database.
30 | */
31 | @NonNullByDefault
32 | public class LinearRing extends LineString
33 | {
34 | private static final long serialVersionUID = 0x100;
35 | // Fake type for linear ring
36 | private static final int TYPE = 0;
37 |
38 | /**
39 | * Constructs an instance.
40 | */
41 | public LinearRing()
42 | {
43 | super(LinearRing.TYPE);
44 | }
45 |
46 | /**
47 | * Constructs an instance.
48 | * @param points points
49 | */
50 | public LinearRing(Iterable points)
51 | {
52 | super(LinearRing.TYPE, points);
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiCurve.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * The MULTICURVE is a collection of curves, which can include linear strings, circular strings or compound strings. It
29 | * only specifies a type of {@link Geometry} as it could contain {@link LineString}s and {@link CompoundCurve}s.
30 | * @author Sebastian Baumhekel
31 | */
32 | @NonNullByDefault
33 | public class MultiCurve extends MultiGeometry
34 | {
35 | /* JDK 1.5 Serialization */
36 | private static final long serialVersionUID = 0x100;
37 | /**
38 | * The OGIS geometry type number for aggregate curves, which can include linear strings, circular strings or
39 | * compound strings.
40 | */
41 | public static final int TYPE = 11;
42 |
43 | /**
44 | * Constructs an instance.
45 | */
46 | public MultiCurve()
47 | {
48 | super(TYPE);
49 | }
50 |
51 | /**
52 | * Constructs an instance.
53 | * @param lines lines
54 | * @throws IllegalArgumentException if given lines are not of a curve type
55 | */
56 | public MultiCurve(Iterable lines)
57 | {
58 | super(TYPE);
59 | for (Curve geom : lines)
60 | {
61 | add(geom);
62 | }
63 | }
64 |
65 | /**
66 | * Gets the length of this line.
67 | * @return length
68 | */
69 | public double length()
70 | {
71 | double d = 0;
72 | for (Geometry ls : subgeoms)
73 | {
74 | if (ls instanceof LineBasedGeometry lbg)
75 | {
76 | d += lbg.length();
77 | }
78 | }
79 | return d;
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiGeometry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collection;
27 | import java.util.Iterator;
28 |
29 | import javax.annotation.Nullable;
30 |
31 | import org.eclipse.jdt.annotation.NonNullByDefault;
32 |
33 | /**
34 | * Base class for multi geometries.
35 | * @author Sebastian Baumhekel
36 | * @param {@link Geometry} type
37 | */
38 | @NonNullByDefault
39 | public abstract class MultiGeometry extends Geometry implements Iterable
40 | {
41 | /* JDK 1.5 Serialization */
42 | private static final long serialVersionUID = 0x100;
43 |
44 | /**
45 | * Sub geometries.
46 | */
47 | protected final ArrayList subgeoms = new ArrayList();
48 |
49 | /**
50 | * Constructs an instance with the specified type.
51 | * @param type int value corresponding to the geometry type
52 | */
53 | protected MultiGeometry(int type)
54 | {
55 | super(type);
56 | }
57 |
58 | /**
59 | * Constructs an instance with the specified type and geometries.
60 | * @param type int value corresponding to the geometry type
61 | * @param geoms geometries
62 | */
63 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS")
64 | protected MultiGeometry(int type, Iterable extends T> geoms)
65 | {
66 | this(type);
67 | this.addAll(geoms);
68 | }
69 |
70 | /**
71 | * Adds a geometry.
72 | * @param geom geometry
73 | */
74 | public void add(T geom)
75 | {
76 | subgeoms.add(geom);
77 | }
78 |
79 | /**
80 | * Adds all given geometries.
81 | * @param geoms geometries
82 | */
83 | public void addAll(Iterable extends T> geoms)
84 | {
85 | for (T geom : geoms)
86 | {
87 | subgeoms.add(geom);
88 | }
89 | }
90 |
91 | @Override
92 | public boolean checkConsistency()
93 | {
94 | if (!super.checkConsistency() || subgeoms.isEmpty())
95 | {
96 | return false;
97 | }
98 | return PostGisUtil.checkConsistency(subgeoms);
99 | }
100 |
101 | @Override
102 | public boolean equals(@Nullable Object other)
103 | {
104 | // check type and parent
105 | if ((other instanceof MultiGeometry> cother) && super.equals(other))
106 | {
107 | return PostGisUtil.equalsIterable(this.subgeoms, cother.subgeoms);
108 | }
109 | return false;
110 | }
111 |
112 | /*
113 | * (non-Javadoc)
114 | * @see io.github.sebasbaumh.postgis.Geometry#getCoordinates()
115 | */
116 | @Override
117 | public Iterable getCoordinates()
118 | {
119 | ArrayList l = new ArrayList();
120 | for (T geom : subgeoms)
121 | {
122 | for (Point p : geom.getCoordinates())
123 | {
124 | l.add(p);
125 | }
126 | }
127 | return l;
128 | }
129 |
130 | /**
131 | * Gets all geometries.
132 | * @return geometries
133 | */
134 | public Collection getGeometries()
135 | {
136 | return subgeoms;
137 | }
138 |
139 | /*
140 | * (non-Javadoc)
141 | * @see io.github.sebasbaumh.postgis.Geometry#getNumberOfCoordinates()
142 | */
143 | @Override
144 | public int getNumberOfCoordinates()
145 | {
146 | int n = 0;
147 | for (T geom : subgeoms)
148 | {
149 | n += geom.getNumberOfCoordinates();
150 | }
151 | return n;
152 | }
153 |
154 | @Override
155 | public int hashCode()
156 | {
157 | return 31 * super.hashCode() + subgeoms.hashCode();
158 | }
159 |
160 | /*
161 | * (non-Javadoc)
162 | * @see io.github.sebasbaumh.postgis.Geometry#hasMeasure()
163 | */
164 | @Override
165 | public boolean hasMeasure()
166 | {
167 | for (T geom : subgeoms)
168 | {
169 | if (geom.hasMeasure())
170 | {
171 | return true;
172 | }
173 | }
174 | return false;
175 | }
176 |
177 | /*
178 | * (non-Javadoc)
179 | * @see io.github.sebasbaumh.postgis.Geometry#is3d()
180 | */
181 | @Override
182 | public boolean is3d()
183 | {
184 | for (T geom : subgeoms)
185 | {
186 | if (geom.is3d())
187 | {
188 | return true;
189 | }
190 | }
191 | return false;
192 | }
193 |
194 | /**
195 | * Checks, if there are no sub-geometries.
196 | * @return true on success, else false
197 | */
198 | @Override
199 | public boolean isEmpty()
200 | {
201 | return subgeoms.isEmpty();
202 | }
203 |
204 | /*
205 | * (non-Javadoc)
206 | * @see java.lang.Iterable#iterator()
207 | */
208 | @Override
209 | public Iterator iterator()
210 | {
211 | return subgeoms.iterator();
212 | }
213 |
214 | @Override
215 | public void setSrid(int srid)
216 | {
217 | super.setSrid(srid);
218 | for (T geom : subgeoms)
219 | {
220 | geom.setSrid(srid);
221 | }
222 | }
223 |
224 | /**
225 | * Gets the number of contained geometries.
226 | * @return number of contained geometries
227 | */
228 | public int size()
229 | {
230 | return this.subgeoms.size();
231 | }
232 |
233 | /*
234 | * (non-Javadoc)
235 | * @see java.lang.Object#toString()
236 | */
237 | @Override
238 | public String toString()
239 | {
240 | return this.getClass().getSimpleName() + " [" + this.size() + " geometries]";
241 | }
242 |
243 | }
244 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiLineString.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * A multi line.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public class MultiLineString extends MultiGeometry
33 | {
34 | /* JDK 1.5 Serialization */
35 | private static final long serialVersionUID = 0x100;
36 | /**
37 | * The OGIS geometry type number for aggregate lines.
38 | */
39 | public static final int TYPE = 5;
40 |
41 | /**
42 | * Constructs an instance.
43 | */
44 | public MultiLineString()
45 | {
46 | super(TYPE);
47 | }
48 |
49 | /**
50 | * Constructs an instance.
51 | * @param lines lines
52 | */
53 | public MultiLineString(Iterable lines)
54 | {
55 | super(TYPE, lines);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiPoint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * A multi point.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public class MultiPoint extends MultiGeometry
33 | {
34 | /* JDK 1.5 Serialization */
35 | private static final long serialVersionUID = 0x100;
36 | /**
37 | * The OGIS geometry type number for aggregate points.
38 | */
39 | public static final int TYPE = 4;
40 |
41 | /**
42 | * Constructs an instance.
43 | */
44 | public MultiPoint()
45 | {
46 | super(TYPE);
47 | }
48 |
49 | /**
50 | * Constructs an instance.
51 | * @param points points
52 | */
53 | public MultiPoint(Iterable points)
54 | {
55 | super(TYPE, points);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiPolygon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * A multi polygon.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public class MultiPolygon extends MultiGeometry
33 | {
34 | /* JDK 1.5 Serialization */
35 | private static final long serialVersionUID = 0x100;
36 | /**
37 | * The OGIS geometry type number for aggregate polygons.
38 | */
39 | public static final int TYPE = 6;
40 |
41 | /**
42 | * Constructs an instance.
43 | */
44 | public MultiPolygon()
45 | {
46 | super(TYPE);
47 | }
48 |
49 | /**
50 | * Constructs an instance.
51 | * @param polygons polygons
52 | */
53 | public MultiPolygon(Iterable polygons)
54 | {
55 | super(TYPE, polygons);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/MultiSurface.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * The MULTISURFACE is a collection of surfaces, which can be (linear) polygons or curve polygons.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public class MultiSurface extends MultiGeometry>
33 | {
34 | private static final long serialVersionUID = 0x100;
35 | /**
36 | * The OGIS geometry type number for multi surfaces, which can be (linear) polygons or curve polygons.
37 | */
38 | public static final int TYPE = 12;
39 |
40 | /**
41 | * Constructs an instance.
42 | */
43 | public MultiSurface()
44 | {
45 | super(TYPE);
46 | }
47 |
48 | /**
49 | * Constructs an instance.
50 | * @param lines lines
51 | */
52 | public > MultiSurface(Iterable lines)
53 | {
54 | super(TYPE);
55 | for (T geom : lines)
56 | {
57 | add(geom);
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGbox2d.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.postgresql.util.PGobject;
28 |
29 | /**
30 | * BOX2D representing the maximum extents of the geometry.
31 | * @author Sebastian Baumhekel
32 | */
33 | public class PGbox2d extends PGboxbase
34 | {
35 | /**
36 | * Type of the {@link PGobject}.
37 | */
38 | private static final String PG_TYPE = "box2d";
39 | /* JDK 1.5 Serialization */
40 | private static final long serialVersionUID = 0x100;
41 |
42 | /**
43 | * Constructs an instance.
44 | */
45 | public PGbox2d()
46 | {
47 | super(PG_TYPE);
48 | }
49 |
50 | /**
51 | * Constructs an instance.
52 | * @param llb lower-left point
53 | * @param urt upper-right point
54 | */
55 | public PGbox2d(Point llb, Point urt)
56 | {
57 | super(PG_TYPE, llb, urt);
58 | }
59 |
60 | /**
61 | * Constructs an instance.
62 | * @param value WKT
63 | * @throws SQLException
64 | */
65 | public PGbox2d(String value) throws SQLException
66 | {
67 | super(PG_TYPE, value);
68 | }
69 |
70 | @Override
71 | public PGbox2d clone() throws CloneNotSupportedException
72 | {
73 | return (PGbox2d)super.clone();
74 | }
75 |
76 | @Override
77 | public String getPrefix()
78 | {
79 | return "BOX";
80 | }
81 |
82 | @Override
83 | public boolean is3d()
84 | {
85 | return false;
86 | }
87 |
88 | @Override
89 | public void setValue(String value) throws SQLException
90 | {
91 | super.setValue(value);
92 | // force 2 dimensions
93 | if (llb.is3d())
94 | {
95 | llb = llb.to2d();
96 | }
97 | if (urt.is3d())
98 | {
99 | urt = urt.to2d();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGbox3d.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.postgresql.util.PGobject;
28 |
29 | /**
30 | * BOX3D representing the maximum extents of the geometry.
31 | * @author Sebastian Baumhekel
32 | */
33 | public class PGbox3d extends PGboxbase
34 | {
35 | /**
36 | * Type of the {@link PGobject}.
37 | */
38 | private static final String PG_TYPE = "box3d";
39 | /* JDK 1.5 Serialization */
40 | private static final long serialVersionUID = 0x100;
41 |
42 | /**
43 | * Constructs an instance.
44 | */
45 | public PGbox3d()
46 | {
47 | super(PG_TYPE);
48 | }
49 |
50 | /**
51 | * Constructs an instance.
52 | * @param llb lower-left point
53 | * @param urt upper-right point
54 | */
55 | public PGbox3d(Point llb, Point urt)
56 | {
57 | super(PG_TYPE, llb, urt);
58 | }
59 |
60 | /**
61 | * Constructs an instance.
62 | * @param value WKT
63 | * @throws SQLException
64 | */
65 | public PGbox3d(String value) throws SQLException
66 | {
67 | super(PG_TYPE, value);
68 | }
69 |
70 | @Override
71 | public PGbox3d clone() throws CloneNotSupportedException
72 | {
73 | return (PGbox3d)super.clone();
74 | }
75 |
76 | @Override
77 | public String getPrefix()
78 | {
79 | return "BOX3D";
80 | }
81 |
82 | @Override
83 | public boolean is3d()
84 | {
85 | return true;
86 | }
87 |
88 | /**
89 | * Gets this {@link Point} as a 2d object.
90 | * @return {@link Point}
91 | */
92 | public PGbox2d to2d()
93 | {
94 | return new PGbox2d(llb.to2d(), urt.to2d());
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGboxbase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 | import java.util.List;
27 | import java.util.Objects;
28 |
29 | import javax.annotation.Nonnull;
30 | import javax.annotation.Nullable;
31 |
32 | import org.eclipse.jdt.annotation.DefaultLocation;
33 | import org.eclipse.jdt.annotation.NonNullByDefault;
34 | import org.postgresql.util.PGobject;
35 |
36 | /**
37 | * Base class for bounding boxes.
38 | * @author Sebastian Baumhekel
39 | */
40 | @NonNullByDefault({ DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE })
41 | public abstract class PGboxbase extends PGobject
42 | {
43 | /* JDK 1.5 Serialization */
44 | private static final long serialVersionUID = 0x100;
45 |
46 | /**
47 | * The lower left bottom corner of the box.
48 | */
49 | protected Point llb;
50 |
51 | /**
52 | * The upper right top corner of the box.
53 | */
54 | protected Point urt;
55 |
56 | /**
57 | * Constructs an instance.
58 | * @param type type of this {@link PGobject}
59 | */
60 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings({ "PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS",
61 | "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" })
62 | protected PGboxbase(String type)
63 | {
64 | this.setType(type);
65 | }
66 |
67 | /**
68 | * Constructs an instance.
69 | * @param type type of this {@link PGobject}
70 | * @param llb lower left {@link Point}
71 | * @param urt upper right {@link Point}
72 | */
73 | protected PGboxbase(String type, Point llb, Point urt)
74 | {
75 | this.setType(type);
76 | this.llb = llb;
77 | this.urt = urt;
78 | }
79 |
80 | /**
81 | * Constructs an instance.
82 | * @param type type of this {@link PGobject}
83 | * @param value WKT
84 | * @throws SQLException
85 | */
86 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings({ "PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS",
87 | "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" })
88 | protected PGboxbase(String type, String value) throws SQLException
89 | {
90 | this.setType(type);
91 | setValue(value);
92 | }
93 |
94 | /**
95 | * Appends a double value to a {@link StringBuilder}. In contrast to {@link StringBuilder#append(double)} it omits a
96 | * 0 decimal like "1.0" it will output "1".
97 | * @param sb {@link StringBuilder}
98 | * @param d double
99 | */
100 | private static void appendDouble(StringBuilder sb, double d)
101 | {
102 | // check for fractional digits (or if the double exceeds the long range)
103 | if (((d % 1.0) != 0) || (d >= Long.MAX_VALUE) || (d <= Long.MIN_VALUE))
104 | {
105 | sb.append(d);
106 | }
107 | else
108 | {
109 | // omit 0-digit
110 | sb.append((long) d);
111 | }
112 | }
113 |
114 | /**
115 | * Converts a point to an inner WKT string like "1 2" or "1 2 3".
116 | * @param sb {@link StringBuilder}
117 | * @param p {@link Point}
118 | */
119 | private static void appendPoint(StringBuilder sb, Point p)
120 | {
121 | PGboxbase.appendDouble(sb, p.getX());
122 | sb.append(' ');
123 | PGboxbase.appendDouble(sb, p.getY());
124 | if (p.is3d())
125 | {
126 | sb.append(' ');
127 | PGboxbase.appendDouble(sb, p.getZ());
128 | }
129 | }
130 |
131 | /**
132 | * Gets a point from an inner WKT string like "1 2" or "1 2 3".
133 | * @param wkt WKT
134 | * @return {@link Point} on success, else null
135 | * @throws NumberFormatException if a coordinate is invalid
136 | */
137 | private static Point pointFromWKT(String wkt)
138 | {
139 | List tokens = PostGisUtil.split(wkt.trim(), ' ');
140 | double x = Double.parseDouble(tokens.get(0));
141 | double y = Double.parseDouble(tokens.get(1));
142 | // 3d?
143 | if (tokens.size() == 3)
144 | {
145 | double z = Double.parseDouble(tokens.get(2));
146 | return new Point(x, y, z);
147 | }
148 | return new Point(x, y);
149 | }
150 |
151 | @Override
152 | public PGboxbase clone() throws CloneNotSupportedException
153 | {
154 | PGboxbase o = (PGboxbase) super.clone();
155 | o.setType(this.getType());
156 | o.llb = llb.copy();
157 | o.urt = urt.copy();
158 | return o;
159 | }
160 |
161 | @Override
162 | public boolean equals(@Nullable Object obj)
163 | {
164 | // short cut
165 | if (this == obj)
166 | {
167 | return true;
168 | }
169 | // check for type and null
170 | if (!(obj instanceof PGboxbase))
171 | {
172 | return false;
173 | }
174 | PGboxbase otherbox = (PGboxbase) obj;
175 | // Compare two coordinates. As the Server always returns Box3D with three dimensions, z==0 equals dimensions==2
176 | return (this.llb.coordsAreEqual(otherbox.llb) && this.urt.coordsAreEqual(otherbox.urt));
177 | }
178 |
179 | /**
180 | * Returns the lower left bottom corner of the box as a Point object
181 | * @return lower left bottom corner of this box
182 | */
183 | public Point getLLB()
184 | {
185 | return llb;
186 | }
187 |
188 | /**
189 | * The Prefix we have in WKT rep. I use an abstract method here so we do not need to replicate the String object in
190 | * every instance.
191 | * @return the prefix, as a string
192 | */
193 | protected abstract String getPrefix();
194 |
195 | /**
196 | * The OGIS geometry type number of this geometry.
197 | * @return the SRID of this geometry
198 | */
199 | public int getSrid()
200 | {
201 | return this.llb.getSrid();
202 | }
203 |
204 | /**
205 | * Returns the upper right top corner of the box as a Point object
206 | * @return upper right top corner of this box
207 | */
208 | public Point getURT()
209 | {
210 | return urt;
211 | }
212 |
213 | @Nonnull
214 | @Override
215 | public String getValue()
216 | {
217 | StringBuilder sb = new StringBuilder();
218 | // add SRID?
219 | int srid = getSrid();
220 | if (srid != Geometry.UNKNOWN_SRID)
221 | {
222 | sb.append("SRID=");
223 | sb.append(srid);
224 | sb.append(';');
225 | }
226 | // write prefix and points
227 | sb.append(getPrefix());
228 | sb.append('(');
229 | PGboxbase.appendPoint(sb, llb);
230 | sb.append(',');
231 | PGboxbase.appendPoint(sb, urt);
232 | sb.append(')');
233 | return sb.toString();
234 | }
235 |
236 | @Override
237 | public int hashCode()
238 | {
239 | return Objects.hash(llb, urt);
240 | }
241 |
242 | /**
243 | * Checks if this box is 3d.
244 | * @return true on success, else false
245 | */
246 | public abstract boolean is3d();
247 |
248 | /**
249 | * Ist this box empty, so does it contain no coordinates?
250 | * @return true on success, else false
251 | */
252 | public boolean isEmpty()
253 | {
254 | return llb.isEmpty() && urt.isEmpty();
255 | }
256 |
257 | /**
258 | * Recursively sets the srid on this geometry and all contained subgeometries
259 | * @param srid the SRID for this geometry
260 | */
261 | public void setSrid(int srid)
262 | {
263 | this.llb.setSrid(srid);
264 | this.urt.setSrid(srid);
265 | }
266 |
267 | @Override
268 | public void setValue(@SuppressWarnings("null") @Nonnull String value) throws SQLException
269 | {
270 | try
271 | {
272 | int srid = Geometry.UNKNOWN_SRID;
273 | value = value.trim();
274 | if (value.startsWith("SRID="))
275 | {
276 | int index = value.indexOf(';', 5); // sridprefix length is 5
277 | if (index < 0)
278 | {
279 | throw new SQLException("Error parsing Geometry - SRID not delimited with ';' ");
280 | }
281 | String sSrid = value.substring(5, index);
282 | value = value.substring(index + 1).trim();
283 | srid = Integer.parseInt(sSrid);
284 | // ensure valid SRID
285 | if (srid < 0)
286 | {
287 | srid = Geometry.UNKNOWN_SRID;
288 | }
289 | }
290 | String myPrefix = getPrefix();
291 | if (value.startsWith(myPrefix))
292 | {
293 | value = value.substring(myPrefix.length()).trim();
294 | }
295 | String valueNoParans = PostGisUtil.removeBrackets(value);
296 | List tokens = PostGisUtil.split(valueNoParans, ',');
297 | llb = PGboxbase.pointFromWKT(tokens.get(0));
298 | urt = PGboxbase.pointFromWKT(tokens.get(1));
299 | if (srid != Geometry.UNKNOWN_SRID)
300 | {
301 | llb.setSrid(srid);
302 | urt.setSrid(srid);
303 | }
304 | }
305 | catch (NumberFormatException | IndexOutOfBoundsException ex)
306 | {
307 | throw new SQLException("Error parsing Point: " + ex.getMessage(), ex);
308 | }
309 | }
310 |
311 | /**
312 | * Unlike geometries, toString() does _not_ contain the srid, as server-side PostGIS cannot parse this.
313 | * @return String representation of this box
314 | */
315 | @Override
316 | public String toString()
317 | {
318 | return getValue();
319 | }
320 | }
321 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGgeography.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.postgresql.util.PGobject;
28 |
29 | /**
30 | * Geometry class for geographic geometries.
31 | * @author Sebastian Baumhekel
32 | */
33 | public class PGgeography extends PGgeometrybase
34 | {
35 | /**
36 | * Type of the {@link PGobject}.
37 | */
38 | private static final String PG_TYPE = "geography";
39 | /* JDK 1.5 Serialization */
40 | private static final long serialVersionUID = 0x100;
41 |
42 | /**
43 | * Constructs an instance.
44 | */
45 | public PGgeography()
46 | {
47 | super(PG_TYPE);
48 | }
49 |
50 | /**
51 | * Constructs an instance.
52 | * @param geom {@link Geometry}
53 | */
54 | public PGgeography(Geometry geom)
55 | {
56 | super(PG_TYPE, geom);
57 | }
58 |
59 | /**
60 | * Constructs an instance.
61 | * @param value geometry
62 | * @throws SQLException
63 | */
64 | public PGgeography(String value) throws SQLException
65 | {
66 | super(PG_TYPE, value);
67 | }
68 |
69 | @Override
70 | public PGgeography clone() throws CloneNotSupportedException
71 | {
72 | return (PGgeography) super.clone();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGgeometry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.postgresql.util.PGobject;
28 |
29 | /**
30 | * Geometry class.
31 | * @author Sebastian Baumhekel
32 | */
33 | public class PGgeometry extends PGgeometrybase
34 | {
35 | /**
36 | * Type of the {@link PGobject}.
37 | */
38 | private static final String PG_TYPE = "geometry";
39 | /* JDK 1.5 Serialization */
40 | private static final long serialVersionUID = 0x100;
41 |
42 | /**
43 | * Constructs an instance.
44 | */
45 | public PGgeometry()
46 | {
47 | super(PG_TYPE);
48 | }
49 |
50 | /**
51 | * Constructs an instance.
52 | * @param geom {@link Geometry}
53 | */
54 | public PGgeometry(Geometry geom)
55 | {
56 | super(PG_TYPE, geom);
57 | }
58 |
59 | /**
60 | * Constructs an instance.
61 | * @param value geometry
62 | * @throws SQLException
63 | */
64 | public PGgeometry(String value) throws SQLException
65 | {
66 | super(PG_TYPE, value);
67 | }
68 |
69 | @Override
70 | public PGgeometry clone() throws CloneNotSupportedException
71 | {
72 | return (PGgeometry) super.clone();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PGgeometrybase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 | import java.util.Objects;
27 |
28 | import javax.annotation.Nonnull;
29 | import javax.annotation.Nullable;
30 |
31 | import org.eclipse.jdt.annotation.DefaultLocation;
32 | import org.eclipse.jdt.annotation.NonNullByDefault;
33 | import org.postgresql.util.PGBinaryObject;
34 | import org.postgresql.util.PGobject;
35 |
36 | import io.github.sebasbaumh.postgis.binary.BinaryParser;
37 | import io.github.sebasbaumh.postgis.binary.BinaryWriter;
38 |
39 | /**
40 | * A PostgreSQL JDBC {@link PGobject} extension data type modeling a "geo" type. This class serves as a common
41 | * superclass for classes such as {@link PGgeometry} and {@link PGgeography} which model more specific type semantics.
42 | * @author Phillip Ross
43 | */
44 | @NonNullByDefault({ DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE })
45 | public abstract class PGgeometrybase extends PGobject implements PGBinaryObject
46 | {
47 | /* JDK 1.5 Serialization */
48 | private static final long serialVersionUID = 0x100;
49 |
50 | /**
51 | * Underlying geometry.
52 | */
53 | @Nullable
54 | protected Geometry geometry;
55 |
56 | /**
57 | * Geometry data as bytes.
58 | */
59 | @Nullable
60 | private byte[] geometryData;
61 |
62 | /**
63 | * Constructs an instance.
64 | * @param type type of this {@link PGobject}
65 | */
66 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
67 | protected PGgeometrybase(String type)
68 | {
69 | this.setType(type);
70 | }
71 |
72 | /**
73 | * Constructs an instance.
74 | * @param type type of this {@link PGobject}
75 | * @param geom {@link Geometry}
76 | */
77 | protected PGgeometrybase(String type, Geometry geom)
78 | {
79 | this.setType(type);
80 | this.geometry = geom;
81 | }
82 |
83 | /**
84 | * Constructs an instance.
85 | * @param type type of this {@link PGobject}
86 | * @param value geometry
87 | * @throws SQLException
88 | */
89 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings({ "PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS",
90 | "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" })
91 | protected PGgeometrybase(String type, String value) throws SQLException
92 | {
93 | this.setType(type);
94 | setValue(value);
95 | }
96 |
97 | @Override
98 | public PGgeometrybase clone() throws CloneNotSupportedException
99 | {
100 | PGgeometrybase o = (PGgeometrybase) super.clone();
101 | o.setType(this.getType());
102 | o.setGeometry(this.getGeometry());
103 | return o;
104 | }
105 |
106 | @Override
107 | public boolean equals(@Nullable Object obj)
108 | {
109 | if (this == obj)
110 | {
111 | return true;
112 | }
113 | if (!(obj instanceof PGgeometrybase))
114 | {
115 | return false;
116 | }
117 | PGgeometrybase other = (PGgeometrybase) obj;
118 | return Objects.equals(this.geometry, other.geometry);
119 | }
120 |
121 | /**
122 | * Gets the binary value.
123 | * @return binary value on success, else null
124 | */
125 | @Nullable
126 | private byte[] getBinaryValue()
127 | {
128 | // short cut
129 | if (this.geometryData != null)
130 | {
131 | return this.geometryData;
132 | }
133 | // check if geometry is there
134 | if (this.geometry != null)
135 | {
136 | // build geometry data and remember it
137 | byte[] data = BinaryWriter.writeBinary(geometry);
138 | this.geometryData = data;
139 | return data;
140 | }
141 | // no geometry
142 | return null;
143 | }
144 |
145 | /**
146 | * Gets the underlying {@link Geometry}.
147 | * @return {@link Geometry} on success, else null
148 | */
149 | @Nullable
150 | public Geometry getGeometry()
151 | {
152 | return geometry;
153 | }
154 |
155 | @Nullable
156 | @Override
157 | public String getValue()
158 | {
159 | if (geometry != null)
160 | {
161 | return BinaryWriter.writeHexed(geometry);
162 | }
163 | return null;
164 | }
165 |
166 | @Override
167 | public int hashCode()
168 | {
169 | return Objects.hashCode(geometry);
170 | }
171 |
172 | @Override
173 | public int lengthInBytes()
174 | {
175 | byte[] data = getBinaryValue();
176 | if (data != null)
177 | {
178 | return data.length;
179 | }
180 | // no geometry
181 | return 0;
182 | }
183 |
184 | @Override
185 | public void setByteValue(@SuppressWarnings("null") byte[] value, int offset) throws SQLException
186 | {
187 | // parse the given bytes
188 | this.geometry = BinaryParser.parse(value, offset);
189 | }
190 |
191 | /**
192 | * Sets the underlying {@link Geometry}.
193 | * @param newgeom {@link Geometry} (can be null)
194 | */
195 | public void setGeometry(@Nullable Geometry newgeom)
196 | {
197 | this.geometry = newgeom;
198 | // reset binary data
199 | this.geometryData = null;
200 | }
201 |
202 | @Override
203 | public void setValue(@SuppressWarnings("null") @Nonnull String value) throws SQLException
204 | {
205 | this.geometry = BinaryParser.parse(value);
206 | // reset binary data
207 | this.geometryData = null;
208 | }
209 |
210 | @Override
211 | public void toBytes(@SuppressWarnings("null") byte[] bytes, int offset)
212 | {
213 | byte[] data = getBinaryValue();
214 | if (data != null)
215 | {
216 | // make sure array is large enough
217 | if ((bytes.length - offset) <= data.length)
218 | {
219 | // copy data
220 | System.arraycopy(data, 0, bytes, offset, data.length);
221 | }
222 | else
223 | {
224 | throw new IllegalArgumentException(
225 | "byte array is too small, expected: " + data.length + " got: " + (bytes.length - offset));
226 | }
227 | }
228 | else
229 | {
230 | throw new IllegalStateException("no geometry has been set");
231 | }
232 | }
233 |
234 | @Override
235 | public String toString()
236 | {
237 | return String.valueOf(geometry);
238 | }
239 |
240 | }
241 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/Point.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.util.Collections;
26 | import java.util.Objects;
27 |
28 | import javax.annotation.Nullable;
29 |
30 | import org.eclipse.jdt.annotation.NonNullByDefault;
31 |
32 | /**
33 | * Point geometry.
34 | * @author Sebastian Baumhekel
35 | */
36 | @NonNullByDefault
37 | public class Point extends Geometry
38 | {
39 | private static final long serialVersionUID = 0x100;
40 |
41 | /**
42 | * The OGIS geometry type number for points.
43 | */
44 | public static final int TYPE = 1;
45 |
46 | /**
47 | * The measure of the point.
48 | */
49 | private double m;
50 |
51 | /**
52 | * The X coordinate of the point. In most long/lat systems, this is the longitude.
53 | */
54 | private double x;
55 |
56 | /**
57 | * The Y coordinate of the point. In most long/lat systems, this is the latitude.
58 | */
59 | private double y;
60 |
61 | /**
62 | * The Z coordinate of the point. In most long/lat systems, this is a radius from the center of the earth, or the
63 | * height / elevation over the ground.
64 | */
65 | private double z;
66 |
67 | /**
68 | * Constructs an empty instance.
69 | */
70 | public Point()
71 | {
72 | this(Double.NaN, Double.NaN, Double.NaN, Double.NaN);
73 | }
74 |
75 | /**
76 | * Constructs a new Point
77 | * @param x the longitude / x ordinate
78 | * @param y the latitude / y ordinate
79 | */
80 | public Point(double x, double y)
81 | {
82 | this(x, y, Double.NaN, Double.NaN);
83 | }
84 |
85 | /**
86 | * Constructs a new Point
87 | * @param x the longitude / x ordinate
88 | * @param y the latitude / y ordinate
89 | * @param z the radius / height / elevation / z ordinate (can be {@link Double#NaN} for no coordinate)
90 | */
91 | public Point(double x, double y, double z)
92 | {
93 | this(x, y, z, Double.NaN);
94 | }
95 |
96 | /**
97 | * Constructs a new Point
98 | * @param x the longitude / x ordinate
99 | * @param y the latitude / y ordinate
100 | * @param z the radius / height / elevation / z ordinate (can be {@link Double#NaN} for no coordinate)
101 | * @param m measure (4th dimension)
102 | */
103 | public Point(double x, double y, double z, double m)
104 | {
105 | super(TYPE);
106 | this.x = x;
107 | this.y = y;
108 | this.z = z;
109 | this.m = m;
110 | }
111 |
112 | @Override
113 | public boolean checkConsistency()
114 | {
115 | return super.checkConsistency() && !Double.isNaN(this.x) && !Double.isNaN(this.y);
116 | }
117 |
118 | /**
119 | * Checks it the coordinates of the given {@link Point} are equal to this {@link Point}.
120 | * @param other {@link Point}
121 | * @return true on success, else false
122 | */
123 | public boolean coordsAreEqual(Point other)
124 | {
125 | return PostGisUtil.equalsDouble(x, other.x) && PostGisUtil.equalsDouble(y, other.y)
126 | && (!is3d() || PostGisUtil.equalsDouble(z, other.z))
127 | && (!hasMeasure() || PostGisUtil.equalsDouble(m, other.m));
128 | }
129 |
130 | /**
131 | * Creates a copy of this {@link Point}.
132 | * @return {@link Point}
133 | */
134 | public Point copy()
135 | {
136 | Point p = new Point(this.x, this.y, this.z, this.m);
137 | p.setSrid(getSrid());
138 | return p;
139 | }
140 |
141 | /**
142 | * Calculates the distance to the given {@link Point}.
143 | * @param p {@link Point}
144 | * @return distance
145 | */
146 | public double distance(Point p)
147 | {
148 | double dX = (p.x - this.x);
149 | double dY = (p.y - this.y);
150 | double d = dX * dX + dY * dY;
151 | if (this.is3d() && p.is3d())
152 | {
153 | double dZ = (p.z - this.z);
154 | d += dZ * dZ;
155 | }
156 | return Math.sqrt(d);
157 | }
158 |
159 | @Override
160 | public boolean equals(@Nullable Object other)
161 | {
162 | // check type and parent
163 | if ((other instanceof Point p) && super.equals(other))
164 | {
165 | return coordsAreEqual(p);
166 | }
167 | return false;
168 | }
169 |
170 | /*
171 | * (non-Javadoc)
172 | * @see io.github.sebasbaumh.postgis.Geometry#getCoordinates()
173 | */
174 | @Override
175 | public Iterable getCoordinates()
176 | {
177 | return Collections.singleton(this);
178 | }
179 |
180 | /**
181 | * Gets the measurement.
182 | * @return measurement on success, else {@link Double#NaN}
183 | */
184 | public double getM()
185 | {
186 | return m;
187 | }
188 |
189 | /*
190 | * (non-Javadoc)
191 | * @see io.github.sebasbaumh.postgis.Geometry#getNumberOfCoordinates()
192 | */
193 | @Override
194 | public int getNumberOfCoordinates()
195 | {
196 | return 1;
197 | }
198 |
199 | /**
200 | * Gets the X-coordinate.
201 | * @return X-coordinate on success, else {@link Double#NaN}
202 | */
203 | public double getX()
204 | {
205 | return x;
206 | }
207 |
208 | /**
209 | * Gets the Y-coordinate.
210 | * @return Y-coordinate on success, else {@link Double#NaN}
211 | */
212 | public double getY()
213 | {
214 | return y;
215 | }
216 |
217 | /**
218 | * Gets the Z-coordinate.
219 | * @return Z-coordinate on success, else {@link Double#NaN}
220 | */
221 | public double getZ()
222 | {
223 | return z;
224 | }
225 |
226 | @Override
227 | public int hashCode()
228 | {
229 | return Objects.hash(x, y, z, m);
230 | }
231 |
232 | /*
233 | * (non-Javadoc)
234 | * @see io.github.sebasbaumh.postgis.Geometry#hasMeasure()
235 | */
236 | @Override
237 | public boolean hasMeasure()
238 | {
239 | return !Double.isNaN(this.m);
240 | }
241 |
242 | /*
243 | * (non-Javadoc)
244 | * @see io.github.sebasbaumh.postgis.Geometry#is3d()
245 | */
246 | @Override
247 | public boolean is3d()
248 | {
249 | return !Double.isNaN(this.z);
250 | }
251 |
252 | /*
253 | * (non-Javadoc)
254 | * @see io.github.sebasbaumh.postgis.Geometry#isEmpty()
255 | */
256 | @Override
257 | public boolean isEmpty()
258 | {
259 | return Double.isNaN(this.x) && Double.isNaN(this.y);
260 | }
261 |
262 | /**
263 | * Sets the measurement.
264 | * @param m measurement
265 | */
266 | public void setM(double m)
267 | {
268 | this.m = m;
269 | }
270 |
271 | /**
272 | * Sets the X-coordinate.
273 | * @param x X-coordinate
274 | */
275 | public void setX(double x)
276 | {
277 | this.x = x;
278 | }
279 |
280 | /**
281 | * Sets the Y-coordinate.
282 | * @param y Y-coordinate
283 | */
284 | public void setY(double y)
285 | {
286 | this.y = y;
287 | }
288 |
289 | /**
290 | * Sets the Z-coordinate.
291 | * @param z Z-coordinate
292 | */
293 | public void setZ(double z)
294 | {
295 | this.z = z;
296 | }
297 |
298 | /**
299 | * Gets this {@link Point} as a 2d object.
300 | * @return {@link Point}
301 | */
302 | public Point to2d()
303 | {
304 | // create a new instance with x/y and measure (if set)
305 | return new Point(this.x, this.y, Double.NaN, this.m);
306 | }
307 |
308 | /*
309 | * (non-Javadoc)
310 | * @see java.lang.Object#toString()
311 | */
312 | @Override
313 | public String toString()
314 | {
315 | StringBuilder sb = new StringBuilder();
316 | sb.append("Point [");
317 | int srid = super.getSrid();
318 | if (srid != UNKNOWN_SRID)
319 | {
320 | sb.append("srid=");
321 | sb.append(srid);
322 | sb.append(',');
323 | }
324 | sb.append(this.x);
325 | sb.append(',');
326 | sb.append(this.y);
327 | if (is3d())
328 | {
329 | sb.append(',');
330 | sb.append(this.z);
331 | }
332 | sb.append(']');
333 | return sb.toString();
334 | }
335 |
336 | }
337 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/Polygon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import org.eclipse.jdt.annotation.NonNullByDefault;
26 |
27 | /**
28 | * A polygon.
29 | * @author Sebastian Baumhekel
30 | */
31 | @NonNullByDefault
32 | public class Polygon extends PolygonBase
33 | {
34 | private static final long serialVersionUID = 0x100;
35 | /**
36 | * The OGIS geometry type number for polygons.
37 | */
38 | public static final int TYPE = 3;
39 |
40 | /**
41 | * Constructs an instance.
42 | */
43 | public Polygon()
44 | {
45 | super(TYPE, LinearRing.class);
46 | }
47 |
48 | /**
49 | * Constructs an instance with the given rings.
50 | * @param rings rings (first one will be the outer ring)
51 | */
52 | public Polygon(Iterable rings)
53 | {
54 | super(TYPE, LinearRing.class, rings);
55 | }
56 |
57 | /**
58 | * Constructs an instance.
59 | * @param lsOuterRing outer ring
60 | */
61 | public Polygon(LinearRing lsOuterRing)
62 | {
63 | super(TYPE, lsOuterRing);
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/PolygonBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.lang.reflect.InvocationTargetException;
26 | import java.util.ArrayList;
27 | import java.util.Iterator;
28 | import java.util.Objects;
29 |
30 | import javax.annotation.Nullable;
31 |
32 | import org.eclipse.jdt.annotation.NonNullByDefault;
33 |
34 | /**
35 | * Base class for a polygon to allow similar handling of straight and circular polygons.
36 | * @author Sebastian Baumhekel
37 | * @param type of the ring geometries
38 | */
39 | @NonNullByDefault
40 | public abstract class PolygonBase extends Geometry implements Iterable, LineBasedGeometry
41 | {
42 | /* JDK 1.5 Serialization */
43 | private static final long serialVersionUID = 0x100;
44 |
45 | private T lsOuterRing;
46 | private final ArrayList rings = new ArrayList();
47 |
48 | /**
49 | * Constructor for subclasses.
50 | * @param clazzRing class of the ring
51 | * @param type has to be given by all subclasses
52 | */
53 | protected PolygonBase(int type, Class clazzRing)
54 | {
55 | super(type);
56 | this.lsOuterRing = createRing(clazzRing);
57 | }
58 |
59 | /**
60 | * Constructor for subclasses.
61 | * @param clazzRing class of the ring
62 | * @param type has to be given by all subclasses
63 | * @param rings rings
64 | */
65 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS")
66 | protected PolygonBase(int type, Class clazzRing, Iterable rings)
67 | {
68 | super(type);
69 | Iterator it = rings.iterator();
70 | // first the outer ring
71 | if (it.hasNext())
72 | {
73 | this.lsOuterRing = it.next();
74 | // inner rings
75 | while (it.hasNext())
76 | {
77 | addRing(it.next());
78 | }
79 | }
80 | else
81 | {
82 | this.lsOuterRing = createRing(clazzRing);
83 | }
84 | }
85 |
86 | /**
87 | * Constructor for subclasses.
88 | * @param type has to be given by all subclasses
89 | * @param lsOuterRing outer ring
90 | */
91 | protected PolygonBase(int type, U lsOuterRing)
92 | {
93 | super(type);
94 | this.lsOuterRing = lsOuterRing;
95 | }
96 |
97 | /**
98 | * Adds a ring.
99 | * @param ring ring
100 | */
101 | public void addRing(T ring)
102 | {
103 | // ensure ring is closed
104 | if (!ring.isClosed())
105 | {
106 | ring.close();
107 | }
108 | // use correct orientation for holes
109 | if (!ring.isClockwise())
110 | {
111 | ring.reverse();
112 | }
113 | this.rings.add(ring);
114 | }
115 |
116 | @Override
117 | public boolean checkConsistency()
118 | {
119 | if (!super.checkConsistency())
120 | {
121 | return false;
122 | }
123 | return PostGisUtil.checkConsistency(rings);
124 | }
125 |
126 | /**
127 | * Clears all rings.
128 | */
129 | public void clearRings()
130 | {
131 | this.rings.clear();
132 | }
133 |
134 | /**
135 | * Creates a new empty ring.
136 | * @param clazzRing class of the ring
137 | * @return ring
138 | * @throws IllegalArgumentException if the class could not be created
139 | */
140 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("EXS_EXCEPTION_SOFTENING_NO_CONSTRAINTS")
141 | private T createRing(Class clazzRing)
142 | {
143 | try
144 | {
145 | return clazzRing.getDeclaredConstructor().newInstance();
146 | }
147 | catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
148 | | NoSuchMethodException | SecurityException e)
149 | {
150 | throw new IllegalArgumentException("unable to create empty ring", e);
151 | }
152 | }
153 |
154 | @Override
155 | public boolean equals(@Nullable Object other)
156 | {
157 | // check type and parent
158 | if ((other instanceof PolygonBase> poly) && super.equals(other))
159 | {
160 | return PostGisUtil.equalsIterable(this.rings, poly.rings);
161 | }
162 | return false;
163 | }
164 |
165 | /*
166 | * (non-Javadoc)
167 | * @see io.github.sebasbaumh.postgis.Geometry#getCoordinates()
168 | */
169 | @Override
170 | public Iterable getCoordinates()
171 | {
172 | return lsOuterRing.getCoordinates();
173 | }
174 |
175 | /*
176 | * (non-Javadoc)
177 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getEndPoint()
178 | */
179 | @Nullable
180 | @Override
181 | public Point getEndPoint()
182 | {
183 | return lsOuterRing.getEndPoint();
184 | }
185 |
186 | /*
187 | * (non-Javadoc)
188 | * @see io.github.sebasbaumh.postgis.Geometry#getNumberOfCoordinates()
189 | */
190 | @Override
191 | public int getNumberOfCoordinates()
192 | {
193 | return lsOuterRing.getNumberOfCoordinates();
194 | }
195 |
196 | /**
197 | * Gets the number of rings.
198 | * @return number of rings.
199 | */
200 | public int getNumberOfRings()
201 | {
202 | return rings.size();
203 | }
204 |
205 | /**
206 | * Gets the outer ring/boundary of the polygon.
207 | * @return outer ring
208 | */
209 | public T getOuterRing()
210 | {
211 | return this.lsOuterRing;
212 | }
213 |
214 | /**
215 | * Gets all inner rings.
216 | * @return inner rings
217 | */
218 | public Iterable getRings()
219 | {
220 | return this.rings;
221 | }
222 |
223 | /*
224 | * (non-Javadoc)
225 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#getStartPoint()
226 | */
227 | @Nullable
228 | @Override
229 | public Point getStartPoint()
230 | {
231 | return lsOuterRing.getStartPoint();
232 | }
233 |
234 | @Override
235 | public int hashCode()
236 | {
237 | return 31 * super.hashCode() + Objects.hash(lsOuterRing, rings);
238 | }
239 |
240 | /*
241 | * (non-Javadoc)
242 | * @see io.github.sebasbaumh.postgis.Geometry#hasMeasure()
243 | */
244 | @Override
245 | public boolean hasMeasure()
246 | {
247 | for (T geom : rings)
248 | {
249 | if (geom.hasMeasure())
250 | {
251 | return true;
252 | }
253 | }
254 | return false;
255 | }
256 |
257 | /*
258 | * (non-Javadoc)
259 | * @see io.github.sebasbaumh.postgis.Geometry#is3d()
260 | */
261 | @Override
262 | public boolean is3d()
263 | {
264 | for (T geom : rings)
265 | {
266 | if (geom.is3d())
267 | {
268 | return true;
269 | }
270 | }
271 | return false;
272 | }
273 |
274 | /**
275 | * Checks if this polygon is oriented in clockwise direction. Is false for the outer polygon and true for its holes.
276 | * @return true on success, else false
277 | */
278 | public boolean isClockwise()
279 | {
280 | return lsOuterRing.isClockwise();
281 | }
282 |
283 | /*
284 | * (non-Javadoc)
285 | * @see io.github.sebasbaumh.postgis.LineBasedGeometry#isClosed()
286 | */
287 | @Override
288 | public boolean isClosed()
289 | {
290 | return this.lsOuterRing.isClosed();
291 | }
292 |
293 | /*
294 | * (non-Javadoc)
295 | * @see io.github.sebasbaumh.postgis.Geometry#isEmpty()
296 | */
297 | @Override
298 | public boolean isEmpty()
299 | {
300 | return lsOuterRing.isEmpty();
301 | }
302 |
303 | /*
304 | * (non-Javadoc)
305 | * @see java.lang.Iterable#iterator()
306 | */
307 | @Override
308 | public Iterator iterator()
309 | {
310 | return this.rings.iterator();
311 | }
312 |
313 | /*
314 | * (non-Javadoc)
315 | * @see io.github.sebasbaumh.postgis.LineBasedGeom#length()
316 | */
317 | @Override
318 | public double length()
319 | {
320 | return this.lsOuterRing.length();
321 | }
322 |
323 | /**
324 | * Sets the outer ring/boundary of the polygon.
325 | * @param ls outer ring
326 | */
327 | public void setOuterRing(T ls)
328 | {
329 | this.lsOuterRing = ls;
330 | }
331 |
332 | /*
333 | * (non-Javadoc)
334 | * @see java.lang.Object#toString()
335 | */
336 | @Override
337 | public String toString()
338 | {
339 | return this.getClass().getSimpleName() + " [" + this.getNumberOfCoordinates() + " points, " + getNumberOfRings()
340 | + " inner rings]";
341 | }
342 |
343 | }
344 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/BinaryParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collection;
27 |
28 | import io.github.sebasbaumh.postgis.CircularString;
29 | import io.github.sebasbaumh.postgis.CompoundCurve;
30 | import io.github.sebasbaumh.postgis.Curve;
31 | import io.github.sebasbaumh.postgis.CurvePolygon;
32 | import io.github.sebasbaumh.postgis.Geometry;
33 | import io.github.sebasbaumh.postgis.GeometryCollection;
34 | import io.github.sebasbaumh.postgis.LineString;
35 | import io.github.sebasbaumh.postgis.LinearRing;
36 | import io.github.sebasbaumh.postgis.MultiCurve;
37 | import io.github.sebasbaumh.postgis.MultiLineString;
38 | import io.github.sebasbaumh.postgis.MultiPoint;
39 | import io.github.sebasbaumh.postgis.MultiPolygon;
40 | import io.github.sebasbaumh.postgis.MultiSurface;
41 | import io.github.sebasbaumh.postgis.Point;
42 | import io.github.sebasbaumh.postgis.Polygon;
43 | import io.github.sebasbaumh.postgis.PolygonBase;
44 |
45 | /**
46 | * A parser for reading geometries from a binary or hex string representation.
47 | * @author Sebastian Baumhekel
48 | */
49 | public final class BinaryParser
50 | {
51 |
52 | // prevent instantiating this class
53 | @Deprecated
54 | private BinaryParser()
55 | {
56 | }
57 |
58 | /**
59 | * Parse a hex encoded geometry
60 | * @param value byte array containing the data to be parsed
61 | * @param offset offset
62 | * @return resulting geometry for the parsed data
63 | * @throws IllegalArgumentException if a contained geometry is of the wrong type or the encoding type is unknown
64 | */
65 | public static Geometry parse(byte[] value, int offset)
66 | {
67 | return parseGeometry(new BinaryValueGetter(value, offset));
68 | }
69 |
70 | /**
71 | * Parse a hex encoded geometry
72 | * @param value String containing the data to be parsed
73 | * @return resulting geometry for the parsed data
74 | * @throws IllegalArgumentException if a contained geometry is of the wrong type or the encoding type is unknown
75 | */
76 | public static Geometry parse(String value)
77 | {
78 | return parseGeometry(new StringValueGetter(value));
79 | }
80 |
81 | /**
82 | * Parse multiple geometries into a {@link Collection}. The number of geometries is read upfront from the
83 | * {@link ValueGetter}.
84 | * @param clazz {@link Class} of the geometries
85 | * @param data {@link ValueGetter}
86 | * @return {@link Collection} of geometries
87 | * @throws IllegalArgumentException if a contained geometry is of the wrong type
88 | */
89 | @SuppressWarnings("unchecked")
90 | private static Collection parseGeometries(Class clazz, ValueGetter data)
91 | {
92 | // get number of geometries to parse
93 | int count = data.getInt();
94 | ArrayList l = new ArrayList(count);
95 | // parse geometries
96 | for (int i = 0; i < count; i++)
97 | {
98 | Geometry geom = parseGeometry(data);
99 | // check if the geometry is of the correct type
100 | if (clazz.isInstance(geom))
101 | {
102 | l.add((T) geom);
103 | }
104 | else
105 | {
106 | throw new IllegalArgumentException(
107 | "expected: " + clazz.getCanonicalName() + " got: " + geom.getClass().getCanonicalName());
108 | }
109 | }
110 | return l;
111 | }
112 |
113 | /**
114 | * Parse a geometry starting at offset.
115 | * @param data ValueGetter with the data to be parsed
116 | * @return the parsed geometry
117 | * @throws IllegalArgumentException for unknown geometry types
118 | */
119 | private static Geometry parseGeometry(ValueGetter data)
120 | {
121 | // read endian flag
122 | data.readEncoding();
123 | // and get the type
124 | int typeword = data.getInt();
125 | int geometryType = typeword & 0x1FFFFFFF; // cut off high flag bits
126 |
127 | boolean haveZ = (typeword & 0x80000000) != 0;
128 | boolean haveM = (typeword & 0x40000000) != 0;
129 | boolean haveS = (typeword & 0x20000000) != 0;
130 |
131 | int srid = Geometry.UNKNOWN_SRID;
132 | if (haveS)
133 | {
134 | // ensure valid SRID
135 | srid = data.getInt();
136 | if (srid < 0)
137 | {
138 | srid = Geometry.UNKNOWN_SRID;
139 | }
140 | }
141 | // parse geometry according to type
142 | Geometry result;
143 | switch (geometryType)
144 | {
145 | case Point.TYPE:
146 | result = parsePoint(data, haveZ, haveM);
147 | break;
148 | case LineString.TYPE:
149 | result = new LineString(parsePoints(data, haveZ, haveM));
150 | break;
151 | case CircularString.TYPE:
152 | result = new CircularString(parsePoints(data, haveZ, haveM));
153 | break;
154 | case CompoundCurve.TYPE:
155 | result = new CompoundCurve(parseGeometries(LineString.class, data));
156 | break;
157 | case Polygon.TYPE:
158 | result = parsePolygon(data, haveZ, haveM);
159 | break;
160 | case CurvePolygon.TYPE:
161 | result = new CurvePolygon(parseGeometries(Curve.class, data));
162 | break;
163 | case MultiPoint.TYPE:
164 | result = new MultiPoint(parseGeometries(Point.class, data));
165 | break;
166 | case MultiLineString.TYPE:
167 | result = new MultiLineString(parseGeometries(LineString.class, data));
168 | break;
169 | case MultiCurve.TYPE:
170 | result = new MultiCurve(parseGeometries(Curve.class, data));
171 | break;
172 | case MultiPolygon.TYPE:
173 | result = new MultiPolygon(parseGeometries(Polygon.class, data));
174 | break;
175 | case MultiSurface.TYPE:
176 | result = new MultiSurface(parseGeometries(PolygonBase.class, data));
177 | break;
178 | case GeometryCollection.TYPE:
179 | result = new GeometryCollection(parseGeometries(Geometry.class, data));
180 | break;
181 | default:
182 | throw new IllegalArgumentException("Unknown Geometry Type: " + geometryType);
183 | }
184 | // set SRID and return the geometry
185 | result.setSrid(srid);
186 | return result;
187 | }
188 |
189 | /**
190 | * Parse a single point.
191 | * @param data {@link ValueGetter}
192 | * @param haveZ parse z value?
193 | * @param haveM parse measure value?
194 | * @return {@link Point}
195 | */
196 | private static Point parsePoint(ValueGetter data, boolean haveZ, boolean haveM)
197 | {
198 | double x = data.getDouble();
199 | double y = data.getDouble();
200 | Point result;
201 | // parse z?
202 | if (haveZ)
203 | {
204 | result = new Point(x, y, data.getDouble());
205 | }
206 | else
207 | {
208 | result = new Point(x, y);
209 | }
210 | // parse measure?
211 | if (haveM)
212 | {
213 | result.setM(data.getDouble());
214 | }
215 | return result;
216 | }
217 |
218 | /**
219 | * Parse an Array of "slim" {@link Point}s (without endianness and type, part of {@link LinearRing} and
220 | * {@link LineString}, but not {@link MultiPoint}!
221 | * @param data {@link ValueGetter}
222 | * @param haveZ parse z value?
223 | * @param haveM parse measure value?
224 | * @return {@link Collection} of {@link Point}s
225 | */
226 | private static Collection parsePoints(ValueGetter data, boolean haveZ, boolean haveM)
227 | {
228 | int count = data.getInt();
229 | ArrayList l = new ArrayList(count);
230 | for (int i = 0; i < count; i++)
231 | {
232 | l.add(parsePoint(data, haveZ, haveM));
233 | }
234 | return l;
235 | }
236 |
237 | /**
238 | * Parse a {@link Polygon}.
239 | * @param data {@link ValueGetter}
240 | * @param haveZ parse z value?
241 | * @param haveM parse measure value?
242 | * @return {@link Polygon}
243 | */
244 | private static Polygon parsePolygon(ValueGetter data, boolean haveZ, boolean haveM)
245 | {
246 | int count = data.getInt();
247 | ArrayList rings = new ArrayList(count);
248 | for (int i = 0; i < count; i++)
249 | {
250 | rings.add(new LinearRing(parsePoints(data, haveZ, haveM)));
251 | }
252 | return new Polygon(rings);
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/BinaryValueGetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | /**
26 | * Allows reading values from a byte array.
27 | * @author Sebastian Baumhekel
28 | */
29 | public class BinaryValueGetter extends ValueGetter
30 | {
31 | private int position;
32 | private final byte[] value;
33 |
34 | /**
35 | * Constructs an instance.
36 | * @param value value
37 | * @param offset offset to use
38 | */
39 | public BinaryValueGetter(byte[] value, int offset)
40 | {
41 | this.value = value;
42 | this.position = offset;
43 | }
44 |
45 | @Override
46 | public int getInt()
47 | {
48 | // get current position and advance it
49 | int index = position;
50 | position += 4;
51 | // be sure to use ints as Java byte is signed
52 | int i1 = (value[index]) & 0xFF;
53 | int i2 = (value[index + 1]) & 0xFF;
54 | int i3 = (value[index + 2]) & 0xFF;
55 | int i4 = (value[index + 3]) & 0xFF;
56 | // optimize by not calling getNextByte() for every byte, but just taking them directly from the array
57 | return funcInt.getInt(i1, i2, i3, i4);
58 | }
59 |
60 | @Override
61 | public long getLong()
62 | {
63 | // get current position and advance it
64 | int index = position;
65 | position += 8;
66 | // be sure to use ints as Java byte is signed
67 | int i1 = (value[index]) & 0xFF;
68 | int i2 = (value[index + 1]) & 0xFF;
69 | int i3 = (value[index + 2]) & 0xFF;
70 | int i4 = (value[index + 3]) & 0xFF;
71 | int i5 = (value[index + 4]) & 0xFF;
72 | int i6 = (value[index + 5]) & 0xFF;
73 | int i7 = (value[index + 6]) & 0xFF;
74 | int i8 = (value[index + 7]) & 0xFF;
75 | // optimize by not calling getNextByte() for every byte, but just taking them directly from the array
76 | return funcLong.getLong(i1, i2, i3, i4, i5, i6, i7, i8);
77 | }
78 |
79 | @Override
80 | protected int getNextByte()
81 | {
82 | // get current position and advance it to the next byte
83 | int index = position;
84 | position++;
85 | // make sure the signed byte in the array gets converted to an unsigned value
86 | return (value[index]) & 0xFF;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/BinaryValueSetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import java.io.ByteArrayOutputStream;
26 |
27 | /**
28 | * Allows writing values to a byte array in little endian format.
29 | * @author Sebastian Baumhekel
30 | */
31 | public class BinaryValueSetter extends ValueSetter
32 | {
33 | private final ByteArrayOutputStream out = new ByteArrayOutputStream();
34 |
35 | /**
36 | * Gets the written value.
37 | * @return value
38 | */
39 | public byte[] getValue()
40 | {
41 | return out.toByteArray();
42 | }
43 |
44 | @Override
45 | public void setByte(byte b)
46 | {
47 | out.write(b);
48 | }
49 |
50 | @Override
51 | public void setInt(int value)
52 | {
53 | out.write((value >>> 0) & 0xFF);
54 | out.write((value >>> 8) & 0xFF);
55 | out.write((value >>> 16) & 0xFF);
56 | out.write((value >>> 24) & 0xFF);
57 | }
58 |
59 | @Override
60 | public void setLong(long value)
61 | {
62 | out.write((int) ((value >>> 0) & 0xFF));
63 | out.write((int) ((value >>> 8) & 0xFF));
64 | out.write((int) ((value >>> 16) & 0xFF));
65 | out.write((int) ((value >>> 24) & 0xFF));
66 | out.write((int) ((value >>> 32) & 0xFF));
67 | out.write((int) ((value >>> 40) & 0xFF));
68 | out.write((int) ((value >>> 48) & 0xFF));
69 | out.write((int) ((value >>> 56) & 0xFF));
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/BinaryWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collection;
27 |
28 | import io.github.sebasbaumh.postgis.CircularString;
29 | import io.github.sebasbaumh.postgis.CompoundCurve;
30 | import io.github.sebasbaumh.postgis.Curve;
31 | import io.github.sebasbaumh.postgis.CurvePolygon;
32 | import io.github.sebasbaumh.postgis.Geometry;
33 | import io.github.sebasbaumh.postgis.GeometryCollection;
34 | import io.github.sebasbaumh.postgis.LineString;
35 | import io.github.sebasbaumh.postgis.LinearRing;
36 | import io.github.sebasbaumh.postgis.MultiCurve;
37 | import io.github.sebasbaumh.postgis.MultiLineString;
38 | import io.github.sebasbaumh.postgis.MultiPoint;
39 | import io.github.sebasbaumh.postgis.MultiPolygon;
40 | import io.github.sebasbaumh.postgis.MultiSurface;
41 | import io.github.sebasbaumh.postgis.Point;
42 | import io.github.sebasbaumh.postgis.Polygon;
43 | import io.github.sebasbaumh.postgis.PolygonBase;
44 | import io.github.sebasbaumh.postgis.PostGisUtil;
45 |
46 | /**
47 | * A writer for building a binary or hex string representation of geometries.
48 | * @author Sebastian Baumhekel
49 | */
50 | public final class BinaryWriter
51 | {
52 | // prevent instantiating this class
53 | @Deprecated
54 | private BinaryWriter()
55 | {
56 | }
57 |
58 | /**
59 | * Write a binary encoded geometry. The geometry you put in must be consistent, geom.checkConsistency() must return
60 | * true. If not, the result may be invalid WKB.
61 | * @see Geometry#checkConsistency() the consistency checker
62 | * @param geom the geometry to be written
63 | * @return byte arrray containing the encoded geometry
64 | */
65 | public static byte[] writeBinary(Geometry geom)
66 | {
67 | BinaryValueSetter bytes = new BinaryValueSetter();
68 | writeGeometry(geom, bytes);
69 | return bytes.getValue();
70 | }
71 |
72 | /**
73 | * Parse a geometry starting at offset.
74 | * @param geom the geometry to write
75 | * @param dest the value setting to be used for writing
76 | */
77 | private static void writeGeometry(Geometry geom, ValueSetter dest)
78 | {
79 | // write endian flag, NDR (little endian)
80 | dest.setByte(PostGisUtil.LITTLE_ENDIAN);
81 |
82 | // write typeword
83 | int typeword = geom.getType();
84 | if (geom.is3d())
85 | {
86 | typeword |= 0x80000000;
87 | }
88 | if (geom.hasMeasure())
89 | {
90 | typeword |= 0x40000000;
91 | }
92 | if (geom.getSrid() != Geometry.UNKNOWN_SRID)
93 | {
94 | typeword |= 0x20000000;
95 | }
96 | dest.setInt(typeword);
97 |
98 | if (geom.getSrid() != Geometry.UNKNOWN_SRID)
99 | {
100 | dest.setInt(geom.getSrid());
101 | }
102 |
103 | switch (geom.getType())
104 | {
105 | case Point.TYPE:
106 | writePoint((Point) geom, dest);
107 | break;
108 | case LineString.TYPE:
109 | writePoints((LineString) geom, dest);
110 | break;
111 | case CircularString.TYPE:
112 | writePoints((CircularString) geom, dest);
113 | break;
114 | case CompoundCurve.TYPE:
115 | writeMultiGeometry(((CompoundCurve) geom).getGeometries(), dest);
116 | break;
117 | case Polygon.TYPE:
118 | writePolygon((Polygon) geom, dest);
119 | break;
120 | case CurvePolygon.TYPE:
121 | writePolygon((CurvePolygon) geom, dest);
122 | break;
123 | case MultiPoint.TYPE:
124 | writeMultiGeometry(((MultiPoint) geom).getGeometries(), dest);
125 | break;
126 | case MultiLineString.TYPE:
127 | writeMultiGeometry(((MultiLineString) geom).getGeometries(), dest);
128 | break;
129 | case MultiCurve.TYPE:
130 | writeMultiGeometry(((MultiCurve) geom).getGeometries(), dest);
131 | break;
132 | case MultiPolygon.TYPE:
133 | writeMultiGeometry(((MultiPolygon) geom).getGeometries(), dest);
134 | break;
135 | case MultiSurface.TYPE:
136 | writeMultiGeometry(((MultiSurface) geom).getGeometries(), dest);
137 | break;
138 | case GeometryCollection.TYPE:
139 | writeMultiGeometry(((GeometryCollection) geom).getGeometries(), dest);
140 | break;
141 | default:
142 | throw new IllegalArgumentException("Unknown Geometry Type: " + geom.getType());
143 | }
144 | }
145 |
146 | /**
147 | * Write a hex encoded geometry. The geometry you put in must be consistent, geom.checkConsistency() must return
148 | * true. If not, the result may be invalid WKB.
149 | * @see Geometry#checkConsistency() the consistency checker
150 | * @param geom the geometry to be written
151 | * @return String containing the hex encoded geometry
152 | */
153 | public static String writeHexed(Geometry geom)
154 | {
155 | StringValueSetter bytes = new StringValueSetter();
156 | writeGeometry(geom, bytes);
157 | return bytes.getValue();
158 | }
159 |
160 | /**
161 | * Writes multiple geometries preceded by their count.
162 | * @param geoms geometries
163 | * @param dest writer
164 | */
165 | private static void writeMultiGeometry(Collection geoms, ValueSetter dest)
166 | {
167 | dest.setInt(geoms.size());
168 | for (Geometry geom : geoms)
169 | {
170 | writeGeometry(geom, dest);
171 | }
172 | }
173 |
174 | /**
175 | * Writes a "slim" Point (without endiannes, srid ant type, only the ordinates and measure. Used by writeGeometry as
176 | * ell as writePointArray.
177 | * @param geom geometry
178 | * @param dest writer
179 | */
180 | private static void writePoint(Point geom, ValueSetter dest)
181 | {
182 | dest.setDouble(geom.getX());
183 | dest.setDouble(geom.getY());
184 | // write z coordinate?
185 | if (geom.is3d())
186 | {
187 | dest.setDouble(geom.getZ());
188 | }
189 | // write measure?
190 | if (geom.hasMeasure())
191 | {
192 | dest.setDouble(geom.getM());
193 | }
194 | }
195 |
196 | /**
197 | * Write an Array of "slim" Points (without endianness, srid and type, part of LinearRing and Linestring, but not
198 | * MultiPoint!
199 | * @param geom geometry
200 | * @param dest writer
201 | */
202 | private static void writePoints(LineString geom, ValueSetter dest)
203 | {
204 | // number of points
205 | dest.setInt(geom.getNumberOfCoordinates());
206 | for (Point p : geom)
207 | {
208 | writePoint(p, dest);
209 | }
210 | }
211 |
212 | /**
213 | * Writes a {@link Polygon}.
214 | * @param geom {@link Polygon}
215 | * @param dest writer
216 | */
217 | private static void writePolygon(PolygonBase geom, ValueSetter dest)
218 | {
219 | // collect all rings (outer ring+inner rings)
220 | ArrayList rings = new ArrayList(geom.getNumberOfRings() + 1);
221 | rings.add(geom.getOuterRing());
222 | for (T ring : geom.getRings())
223 | {
224 | rings.add(ring);
225 | }
226 | // write number of rings
227 | dest.setInt(rings.size());
228 | // then all rings
229 | for (T ring : rings)
230 | {
231 | // polygon linear rings are just written as a plain set of points
232 | if (ring instanceof LinearRing lr)
233 | {
234 | writePoints(lr, dest);
235 | }
236 | else
237 | {
238 | // curve polygons can have different geometries
239 | writeGeometry(ring, dest);
240 | }
241 | }
242 | }
243 |
244 | }
245 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/StringValueGetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import io.github.sebasbaumh.postgis.PostGisUtil;
26 |
27 | /**
28 | * Allows reading values from a string.
29 | * @author Sebastian Baumhekel
30 | */
31 | public class StringValueGetter extends ValueGetter
32 | {
33 | private int position;
34 | private final String value;
35 |
36 | /**
37 | * Constructs an instance.
38 | * @param value value as hex string
39 | */
40 | public StringValueGetter(String value)
41 | {
42 | this.value = value;
43 | }
44 |
45 | @Override
46 | protected int getNextByte()
47 | {
48 | // get current position (and respect that every byte consists of 2 hex characters)
49 | int index = position * 2;
50 | // then advance the position to the next byte
51 | position++;
52 | return ((PostGisUtil.toHexByte(value.charAt(index)) << 4) | PostGisUtil.toHexByte(value.charAt(index + 1)));
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/StringValueSetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import io.github.sebasbaumh.postgis.PostGisUtil;
26 |
27 | /**
28 | * Allows writing values as a string in little endian encoding and hex format.
29 | * @author Sebastian Baumhekel
30 | */
31 | public class StringValueSetter extends ValueSetter
32 | {
33 | private final StringBuilder sb = new StringBuilder();
34 |
35 | /**
36 | * Constructs an instance.
37 | */
38 | public StringValueSetter()
39 | {
40 | }
41 |
42 | /**
43 | * Gets the written value.
44 | * @return value
45 | */
46 | public String getValue()
47 | {
48 | return sb.toString();
49 | }
50 |
51 | @Override
52 | public void setByte(byte b)
53 | {
54 | sb.append(PostGisUtil.HEX_CHAR[(b >> 4) & 0xF]);
55 | sb.append(PostGisUtil.HEX_CHAR[b & 0xF]);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/ValueGetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | import io.github.sebasbaumh.postgis.PostGisUtil;
26 |
27 | /**
28 | * A base class for value readers.
29 | * @author Sebastian Baumhekel
30 | */
31 | public abstract class ValueGetter
32 | {
33 |
34 | /**
35 | * Int builder for big endian encoding.
36 | */
37 | private static final IntBuilder INT_BUILDER_BIG_ENDIAN = (b1, b2, b3, b4) ->
38 | (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
39 |
40 | /**
41 | * Int builder for little endian encoding.
42 | */
43 | private static final IntBuilder INT_BUILDER_LITTLE_ENDIAN = (b1, b2, b3, b4) ->
44 | (b4 << 24) + (b3 << 16) + (b2 << 8) + b1;
45 |
46 | /**
47 | * Int builder for big endian encoding.
48 | */
49 | private static final LongBuilder LONG_BUILDER_BIG_ENDIAN = (b1, b2, b3, b4, b5, b6, b7, b8) ->
50 | (b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32) + (b5 << 24) + (b6 << 16) + (b7 << 8) + b8;
51 |
52 | /**
53 | * Int builder for little endian encoding.
54 | */
55 | private static final LongBuilder LONG_BUILDER_LITTLE_ENDIAN = (b1, b2, b3, b4, b5, b6, b7, b8) ->
56 | (b8 << 56) + (b7 << 48) + (b6 << 40) + (b5 << 32) + (b4 << 24) + (b3 << 16) + (b2 << 8) + b1;
57 |
58 | /**
59 | * Current encoding (default is little endian encoding).
60 | */
61 | protected int endian = PostGisUtil.LITTLE_ENDIAN;
62 | /**
63 | * Builder for integer values respecting the current encoding (default is little endian encoding).
64 | */
65 | protected IntBuilder funcInt = INT_BUILDER_LITTLE_ENDIAN;
66 | /**
67 | * Builder for long values respecting the current encoding (default is little endian encoding).
68 | */
69 | protected LongBuilder funcLong = LONG_BUILDER_LITTLE_ENDIAN;
70 |
71 | /**
72 | * Constructs an instance.
73 | */
74 | public ValueGetter()
75 | {
76 | }
77 |
78 | /**
79 | * Get a double value.
80 | * @return double value
81 | */
82 | public double getDouble()
83 | {
84 | return Double.longBitsToDouble(getLong());
85 | }
86 |
87 | /**
88 | * Get an integer value.
89 | * @return integer value
90 | */
91 | public int getInt()
92 | {
93 | return funcInt.getInt(getNextByte(), getNextByte(), getNextByte(), getNextByte());
94 | }
95 |
96 | /**
97 | * Get a long value.
98 | * @return long value
99 | */
100 | public long getLong()
101 | {
102 | return funcLong.getLong(getNextByte(), getNextByte(), getNextByte(), getNextByte(), getNextByte(),
103 | getNextByte(), getNextByte(), getNextByte());
104 | }
105 |
106 | /**
107 | * Gets a byte at the current index.
108 | * @return byte
109 | * @throws IndexOutOfBoundsException if the current index is out of the range
110 | */
111 | protected abstract int getNextByte();
112 |
113 | /**
114 | * Reads the encoding and adjusts the internal decoder if necessary.
115 | * @throws IllegalArgumentException if the endian type is unknown
116 | */
117 | public void readEncoding()
118 | {
119 | // get byte for endian check
120 | int newEndian = getNextByte();
121 | // only do something if encoding differs from the current setting
122 | if (newEndian != this.endian)
123 | {
124 | this.endian = newEndian;
125 | switch (newEndian)
126 | {
127 | case PostGisUtil.LITTLE_ENDIAN:
128 | {
129 | this.funcInt = INT_BUILDER_LITTLE_ENDIAN;
130 | this.funcLong = LONG_BUILDER_LITTLE_ENDIAN;
131 | }
132 | break;
133 | case PostGisUtil.BIG_ENDIAN:
134 | {
135 | this.funcInt = INT_BUILDER_BIG_ENDIAN;
136 | this.funcLong = LONG_BUILDER_BIG_ENDIAN;
137 | }
138 | break;
139 | default:
140 | throw new IllegalArgumentException("Unknown Endian type:" + endian);
141 | }
142 | }
143 | }
144 |
145 | /**
146 | * Builder for an int from a byte sequence.
147 | */
148 | @FunctionalInterface
149 | protected interface IntBuilder
150 | {
151 | /**
152 | * Get an integer.
153 | * @param b1 byte 1
154 | * @param b2 byte 2
155 | * @param b3 byte 3
156 | * @param b4 byte 4
157 | * @return integer
158 | */
159 | int getInt(int b1, int b2, int b3, int b4);
160 | }
161 |
162 | /**
163 | * Builder for a long from a byte sequence.
164 | */
165 | @FunctionalInterface
166 | protected interface LongBuilder
167 | {
168 | /**
169 | * Get a long.
170 | * @param b1 byte 1
171 | * @param b2 byte 2
172 | * @param b3 byte 3
173 | * @param b4 byte 4
174 | * @param b5 byte 5
175 | * @param b6 byte 6
176 | * @param b7 byte 7
177 | * @param b8 byte 8
178 | * @return long
179 | */
180 | long getLong(long b1, long b2, long b3, long b4, long b5, long b6, long b7, long b8);
181 | }
182 |
183 | }
184 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/ValueSetter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis.binary;
24 |
25 | /**
26 | * A base class for value setters.
27 | * @author Sebastian Baumhekel
28 | */
29 | public abstract class ValueSetter
30 | {
31 |
32 | /**
33 | * Constructs an instance.
34 | */
35 | public ValueSetter()
36 | {
37 | }
38 |
39 | /**
40 | * Sets a byte.
41 | * @param b byte value to set with
42 | */
43 | public abstract void setByte(byte b);
44 |
45 | /**
46 | * Writes a double.
47 | * @param data double value to be set with
48 | */
49 | public void setDouble(double data)
50 | {
51 | setLong(Double.doubleToLongBits(data));
52 | }
53 |
54 | /**
55 | * Sets a 32-Bit integer
56 | * @param value int value to be set with
57 | */
58 | public void setInt(int value)
59 | {
60 | setByte((byte) value);
61 | setByte((byte) (value >> 8));
62 | setByte((byte) (value >> 16));
63 | setByte((byte) (value >> 24));
64 | }
65 |
66 | /**
67 | * Sets a long value. This is not needed directly, but as a nice side-effect from setDouble.
68 | * @param value value value to be set with
69 | */
70 | public void setLong(long value)
71 | {
72 | setByte((byte) value);
73 | setByte((byte) (value >> 8));
74 | setByte((byte) (value >> 16));
75 | setByte((byte) (value >> 24));
76 | setByte((byte) (value >> 32));
77 | setByte((byte) (value >> 40));
78 | setByte((byte) (value >> 48));
79 | setByte((byte) (value >> 56));
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/io/github/sebasbaumh/postgis/binary/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Binary parser package.
3 | * @author Sebastian Baumhekel
4 | */
5 | @org.eclipse.jdt.annotation.NonNullByDefault
6 | package io.github.sebasbaumh.postgis.binary;
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/java.sql.Driver:
--------------------------------------------------------------------------------
1 | io.github.sebasbaumh.postgis.DriverWrapper
--------------------------------------------------------------------------------
/src/main/resources/org/postgresql/driverconfig.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This property file is included in the postgis jar and autoregisters the
3 | # PostGIS datatypes within the jdbc driver.
4 | #
5 |
6 | datatype.geometry=io.github.sebasbaumh.postgis.PGgeometry
7 | datatype.geography=io.github.sebasbaumh.postgis.PGgeography
8 | datatype.box2d=io.github.sebasbaumh.postgis.PGbox2d
9 | datatype.box3d=io.github.sebasbaumh.postgis.PGbox3d
10 | datatype.public.geometry=io.github.sebasbaumh.postgis.PGgeometry
11 | datatype.public.geography=io.github.sebasbaumh.postgis.PGgeography
12 | datatype.public.box2d=io.github.sebasbaumh.postgis.PGbox2d
13 | datatype.public.box3d=io.github.sebasbaumh.postgis.PGbox3d
14 |
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/BoxesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.junit.Assert;
28 | import org.junit.Test;
29 | import org.postgresql.util.PGobject;
30 |
31 | @SuppressWarnings({ "javadoc", "static-method" })
32 | public class BoxesTest
33 | {
34 |
35 | private static void cloneTest(T o)
36 | {
37 | try
38 | {
39 | Object o2 = o.clone();
40 | Assert.assertEquals(o.getClass(), o2.getClass());
41 | @SuppressWarnings("unchecked")
42 | T t2 = (T) o2;
43 | Assert.assertEquals(o, o2);
44 | Assert.assertEquals(o.getType(), t2.getType());
45 | Assert.assertNotSame(o, o2);
46 | }
47 | catch (CloneNotSupportedException ex)
48 | {
49 | Assert.fail("Clone not supported: " + ex.getMessage());
50 | }
51 | }
52 |
53 | @Test
54 | public void testBox2d() throws SQLException
55 | {
56 | PGbox2d box = new PGbox2d("BOX(1 2,3 4)");
57 | Point p0 = box.getLLB();
58 | Assert.assertNotNull(p0);
59 | Assert.assertEquals(1, p0.getX(), 0.0001);
60 | Assert.assertEquals(2, p0.getY(), 0.0001);
61 | Assert.assertFalse(p0.is3d());
62 | Point p1 = box.getURT();
63 | Assert.assertNotNull(p1);
64 | Assert.assertEquals(3, p1.getX(), 0.0001);
65 | Assert.assertEquals(4, p1.getY(), 0.0001);
66 | Assert.assertFalse(p1.is3d());
67 | }
68 |
69 | @Test
70 | public void testBox3d() throws SQLException
71 | {
72 | PGbox3d box = new PGbox3d("BOX3D(1 2 3,4 5 6)");
73 | Point p0 = box.getLLB();
74 | Assert.assertNotNull(p0);
75 | Assert.assertEquals(1, p0.getX(), 0.0001);
76 | Assert.assertEquals(2, p0.getY(), 0.0001);
77 | Assert.assertEquals(3, p0.getZ(), 0.0001);
78 | Assert.assertTrue(p0.is3d());
79 | Point p1 = box.getURT();
80 | Assert.assertNotNull(p1);
81 | Assert.assertEquals(4, p1.getX(), 0.0001);
82 | Assert.assertEquals(5, p1.getY(), 0.0001);
83 | Assert.assertEquals(6, p1.getZ(), 0.0001);
84 | Assert.assertTrue(p1.is3d());
85 | }
86 |
87 | @Test
88 | public void testBox3d_2() throws SQLException
89 | {
90 | PGbox3d box = new PGbox3d("BOX3D(1 2,4 5)");
91 | Point p0 = box.getLLB();
92 | Assert.assertNotNull(p0);
93 | Assert.assertEquals(1, p0.getX(), 0.0001);
94 | Assert.assertEquals(2, p0.getY(), 0.0001);
95 | Assert.assertFalse(p0.is3d());
96 | Point p1 = box.getURT();
97 | Assert.assertNotNull(p1);
98 | Assert.assertEquals(4, p1.getX(), 0.0001);
99 | Assert.assertEquals(5, p1.getY(), 0.0001);
100 | Assert.assertFalse(p1.is3d());
101 | }
102 |
103 | @Test
104 | public void testClone() throws SQLException
105 | {
106 | cloneTest(new PGbox2d("BOX(1 2,3 4)"));
107 | cloneTest(new PGbox3d("BOX3D(1 2 3,4 5 6)"));
108 | cloneTest(new PGbox3d("BOX3D(1 2,4 5)"));
109 | }
110 |
111 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/DatatypesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.junit.Test;
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | @SuppressWarnings("javadoc")
32 | public class DatatypesTest extends DatabaseTestBase
33 | {
34 |
35 | private static final String CR_STR = "CIRCULARSTRING(-9 2,-8 3,-7 2)";
36 |
37 | private static final String CR_STR2 = "CIRCULARSTRING(0 -1,-1 0,0 1,1 0,0 -1)";
38 |
39 | private static final String LNG_STR = "LINESTRING (10 10 20,20 20 20, 50 50 50, 34 34 34)";
40 |
41 | private static final Logger logger = LoggerFactory.getLogger(DatatypesTest.class);
42 |
43 | private static final String MLNG_STR = "MULTILINESTRING ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
44 |
45 | private static final String MPLG_STR = "MULTIPOLYGON (((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))";
46 |
47 | private static final String PLG_STR = "POLYGON ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
48 |
49 | private static final String PTG_STR = "POINT(10 10 20)";
50 |
51 | @SuppressWarnings("unchecked")
52 | private T assertGeometry(Class clazz, String wkt) throws SQLException
53 | {
54 | Geometry geom = getGeometryFromWKT(wkt);
55 | if (clazz.isInstance(geom))
56 | {
57 | return (T) geom;
58 | }
59 | throw new IllegalArgumentException(
60 | "expected: " + clazz.getCanonicalName() + " got: " + geom.getClass().getCanonicalName());
61 | }
62 |
63 | @Test
64 | public void testCircularString() throws SQLException
65 | {
66 | if (!hasDatabase())
67 | {
68 | return;
69 | }
70 | logger.trace("void testCircularString()");
71 | logger.debug(CR_STR);
72 | CircularString lng = assertGeometry(CircularString.class, CR_STR);
73 | logger.debug(lng.toString());
74 | }
75 |
76 | @Test
77 | public void testCircularString2() throws SQLException
78 | {
79 | if (!hasDatabase())
80 | {
81 | return;
82 | }
83 | logger.trace("void testCircularString2()");
84 | logger.debug(CR_STR2);
85 | CircularString lng = assertGeometry(CircularString.class, CR_STR2);
86 | logger.debug(lng.toString());
87 | }
88 |
89 | @Test
90 | public void testLineString() throws SQLException
91 | {
92 | if (!hasDatabase())
93 | {
94 | return;
95 | }
96 | logger.trace("void testLineString()");
97 | logger.debug(LNG_STR);
98 | LineString lng = assertGeometry(LineString.class, LNG_STR);
99 | logger.debug(lng.toString());
100 | }
101 |
102 | @Test
103 | public void testMultiLineString() throws SQLException
104 | {
105 | if (!hasDatabase())
106 | {
107 | return;
108 | }
109 | logger.trace("void testMultiLineString()");
110 | logger.debug(MLNG_STR);
111 | MultiLineString mlng = assertGeometry(MultiLineString.class, MLNG_STR);
112 | logger.debug(mlng.toString());
113 | }
114 |
115 | @Test
116 | public void testMultiPolygon() throws SQLException
117 | {
118 | if (!hasDatabase())
119 | {
120 | return;
121 | }
122 | logger.trace("void testMultiPolygon()");
123 | logger.debug(MPLG_STR);
124 | MultiPolygon mplg = assertGeometry(MultiPolygon.class, MPLG_STR);
125 | logger.debug(mplg.toString());
126 | }
127 |
128 | @Test
129 | public void testPGgeometry() throws SQLException
130 | {
131 | if (!hasDatabase())
132 | {
133 | return;
134 | }
135 | logger.trace("void testPGgeometry()");
136 | logger.debug(MLNG_STR);
137 | PGgeometry pgf = new PGgeometry(getWKBFromWKT(MLNG_STR));
138 | logger.debug(pgf.toString());
139 | }
140 |
141 | @Test
142 | public void testPoint() throws SQLException
143 | {
144 | if (!hasDatabase())
145 | {
146 | return;
147 | }
148 | logger.trace("void testPoint()");
149 | logger.debug(PTG_STR);
150 | Point ptg = assertGeometry(Point.class, PTG_STR);
151 | logger.debug(ptg.toString());
152 | }
153 |
154 | @Test
155 | public void testPolygon() throws SQLException
156 | {
157 | if (!hasDatabase())
158 | {
159 | return;
160 | }
161 | logger.trace("void testPolygon()");
162 | logger.debug(PLG_STR);
163 | Polygon plg = assertGeometry(Polygon.class, PLG_STR);
164 | logger.debug(plg.toString());
165 | }
166 |
167 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/DriverWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Connection;
26 | import java.sql.DriverManager;
27 | import java.sql.ResultSet;
28 | import java.sql.SQLException;
29 | import java.sql.Statement;
30 |
31 | import javax.sql.DataSource;
32 |
33 | import org.junit.Assert;
34 | import org.junit.Test;
35 |
36 | /**
37 | * Test PostGIS connection.
38 | * @author Sebastian Baumhekel
39 | */
40 | @SuppressWarnings("javadoc")
41 | public class DriverWrapperTest extends DatabaseTestBase
42 | {
43 | @Test
44 | public void testPooled() throws Exception
45 | {
46 | if (!hasDatabase())
47 | {
48 | return;
49 | }
50 | DataSource ds = getPooledDataSource();
51 | try (Connection conn = ds.getConnection())
52 | {
53 | DriverWrapper.registerDataTypes(conn);
54 | try (Statement st = conn.createStatement())
55 | {
56 | try (ResultSet rs = st.executeQuery("SELECT postgis_version()"))
57 | {
58 | Assert.assertTrue(rs.next());
59 | Assert.assertNotNull(rs.getString(1));
60 | }
61 | }
62 | }
63 | closeDataSource(ds);
64 | }
65 |
66 | // test based on https://github.com/postgis/postgis-java/pull/115
67 | @SuppressWarnings({ "static-method", "resource" })
68 | @Test
69 | public void testThatPostGisDoesNotOverwriteSavedExceptionForUnsupportedConnectionString()
70 | {
71 | try
72 | {
73 | DriverManager.getConnection("jdbc:missing");
74 | }
75 | catch (SQLException e)
76 | {
77 | // This should not be "Unknown protocol or subprotocol in url jdbc:missing", which
78 | // would indicate that PostGIS threw an exception instead of returning `null` from
79 | // the `connect` method for an unsupported connection string.
80 | // (This is documented in `java.sql.Driver.connect`.)
81 | //
82 | // The former behavior is not desirable as throwing an exception causes a previously
83 | // saved exception from a "better fitting" driver to be overwritten by PostGis, despite
84 | // PostGis not actually being able to handle the connection.
85 | //
86 | // (Imagine an Oracle connection string with a wrong password, in which the Oracle
87 | // driver's exception regarding the wrong password would be replaced with a generic
88 | // nonsensical PostGis exception.)
89 | Assert.assertEquals("No suitable driver found for jdbc:missing", e.getMessage());
90 | }
91 | }
92 |
93 | @Test
94 | public void testUnpooled() throws Exception
95 | {
96 | if (!hasDatabase())
97 | {
98 | return;
99 | }
100 | DataSource ds = getUnpooledDataSource();
101 | try (Connection conn = ds.getConnection())
102 | {
103 | DriverWrapper.registerDataTypes(conn);
104 | try (Statement st = conn.createStatement())
105 | {
106 | try (ResultSet rs = st.executeQuery("SELECT postgis_version()"))
107 | {
108 | Assert.assertTrue(rs.next());
109 | Assert.assertNotNull(rs.getString(1));
110 | }
111 | }
112 | }
113 | closeDataSource(ds);
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/EmptyGeometriesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Connection;
26 | import java.sql.PreparedStatement;
27 | import java.sql.ResultSet;
28 | import java.sql.SQLException;
29 | import java.sql.Statement;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | import org.junit.Test;
34 | import org.slf4j.Logger;
35 | import org.slf4j.LoggerFactory;
36 |
37 | /**
38 | * This class contains tests for handling of empty geometries.
39 | * @author Phillip Ross {@literal }
40 | */
41 | @SuppressWarnings("javadoc")
42 | public class EmptyGeometriesTest extends DatabaseTestBase
43 | {
44 | private static final String[] castTypes = new String[] { "bytea", "text", "geometry" };
45 |
46 | private static final String[] geometriesToTest = new String[] { "POINT", "LINESTRING", "POLYGON", "MULTIPOINT",
47 | "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION", };
48 |
49 | private static final Logger logger = LoggerFactory.getLogger(EmptyGeometriesTest.class);
50 |
51 | private Connection connection = null;
52 |
53 | private Statement statement = null;
54 |
55 | private static List generateSqlStatements()
56 | {
57 | List sqlStatementList = new ArrayList<>();
58 | for (String geometry : geometriesToTest)
59 | {
60 | StringBuilder stringBuilder = new StringBuilder("select ");
61 | for (String castType : castTypes)
62 | {
63 | stringBuilder.append("geometry_in('").append(geometry).append(" EMPTY')::").append(castType)
64 | .append(", ");
65 | }
66 | String sqlStatement = stringBuilder.substring(0, stringBuilder.lastIndexOf(","));
67 | logger.debug("generate sql statement: {}", sqlStatement);
68 | sqlStatementList.add(sqlStatement);
69 | }
70 | return sqlStatementList;
71 | }
72 |
73 | /*
74 | * (non-Javadoc)
75 | * @see io.github.sebasbaumh.postgis.DatabaseTest#afterDatabaseSetup()
76 | */
77 | @Override
78 | protected void afterDatabaseSetup() throws SQLException
79 | {
80 | connection = getConnection();
81 | statement = connection.createStatement();
82 | }
83 |
84 | /*
85 | * (non-Javadoc)
86 | * @see io.github.sebasbaumh.postgis.DatabaseTest#beforeDatabaseShutdown()
87 | */
88 | @Override
89 | protected void beforeDatabaseShutdown() throws SQLException
90 | {
91 | if ((statement != null) && (!statement.isClosed()))
92 | {
93 | statement.close();
94 | }
95 | if ((connection != null) && (!connection.isClosed()))
96 | {
97 | connection.close();
98 | }
99 | }
100 |
101 | @Test
102 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("SQL_INJECTION_JDBC")
103 | public void testSqlStatements() throws SQLException
104 | {
105 | if (!hasDatabase())
106 | {
107 | return;
108 | }
109 | for (String sqlStatement : generateSqlStatements())
110 | {
111 | logger.debug("**********");
112 | logger.debug("* Executing sql statemnent => [{}]", sqlStatement);
113 | logger.debug("**********");
114 | try (PreparedStatement preparedStatement = connection.prepareStatement(sqlStatement);
115 | ResultSet resultSet = preparedStatement.executeQuery())
116 | {
117 | resultSet.next();
118 | for (int i = 1; i <= 3; i++)
119 | {
120 | Object resultSetObject = resultSet.getObject(i);
121 | logger.debug("returned resultSetObject {} => (class=[{}]) {}", i,
122 | resultSetObject.getClass().getName(), resultSetObject);
123 | }
124 | }
125 | }
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/GeographyTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.SQLException;
26 |
27 | import org.junit.Test;
28 |
29 | /**
30 | * Test geometries of geography type.
31 | * @author Sebastian Baumhekel
32 | */
33 | @SuppressWarnings("javadoc")
34 | public class GeographyTest extends PostgisDatabaseTest
35 | {
36 | private static final String LNG_STR = "LINESTRING (10 10 20,20 20 20, 50 50 50, 34 34 34)";
37 |
38 | private static final String MLNG_STR = "MULTILINESTRING ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
39 |
40 | private static final String MPLG_STR = "MULTIPOLYGON (((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))";
41 |
42 | private static final String PLG_STR = "POLYGON ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
43 |
44 | private static final String PTG_STR = "POINT(10 10 20)";
45 |
46 | @SuppressWarnings("unchecked")
47 | private T assertGeometry(Class clazz, String wkt) throws SQLException
48 | {
49 | Geometry geom = getGeographyGeometryFromWKT(wkt);
50 | if (clazz.isInstance(geom))
51 | {
52 | return (T) geom;
53 | }
54 | throw new IllegalArgumentException(
55 | "expected: " + clazz.getCanonicalName() + " got: " + geom.getClass().getCanonicalName());
56 | }
57 |
58 | @Test
59 | public void testLineString() throws SQLException
60 | {
61 | if (!hasDatabase())
62 | {
63 | return;
64 | }
65 | assertGeometry(LineString.class, LNG_STR);
66 | }
67 |
68 | @Test
69 | public void testMultiLineString() throws SQLException
70 | {
71 | if (!hasDatabase())
72 | {
73 | return;
74 | }
75 | assertGeometry(MultiLineString.class, MLNG_STR);
76 | }
77 |
78 | @Test
79 | public void testMultiPolygon() throws SQLException
80 | {
81 | if (!hasDatabase())
82 | {
83 | return;
84 | }
85 | assertGeometry(MultiPolygon.class, MPLG_STR);
86 | }
87 |
88 | @SuppressWarnings("unused")
89 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
90 | @Test
91 | public void testPGgeometry() throws SQLException
92 | {
93 | if (!hasDatabase())
94 | {
95 | return;
96 | }
97 | new PGgeometry(getWKBFromWKT(MLNG_STR));
98 | }
99 |
100 | @Test
101 | public void testPoint() throws SQLException
102 | {
103 | if (!hasDatabase())
104 | {
105 | return;
106 | }
107 | assertGeometry(Point.class, PTG_STR);
108 | }
109 |
110 | @Test
111 | public void testPolygon() throws SQLException
112 | {
113 | if (!hasDatabase())
114 | {
115 | return;
116 | }
117 | assertGeometry(Polygon.class, PLG_STR);
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/PostgisDatabaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Connection;
26 | import java.sql.ResultSet;
27 | import java.sql.SQLException;
28 | import java.sql.Statement;
29 |
30 | import org.junit.Assert;
31 | import org.junit.Test;
32 |
33 | /**
34 | * Test PostGIS connection.
35 | * @author Sebastian Baumhekel
36 | */
37 | @SuppressWarnings("javadoc")
38 | public class PostgisDatabaseTest extends DatabaseTestBase
39 | {
40 |
41 | @Test
42 | public void test() throws SQLException
43 | {
44 | if (!hasDatabase())
45 | {
46 | return;
47 | }
48 | try (Connection conn = getConnection())
49 | {
50 | try (Statement st = conn.createStatement())
51 | {
52 | try (ResultSet rs = st.executeQuery("SELECT postgis_version()"))
53 | {
54 | Assert.assertTrue(rs.next());
55 | Assert.assertNotNull(rs.getString(1));
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/SerializationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.io.ByteArrayOutputStream;
26 | import java.io.NotSerializableException;
27 | import java.io.ObjectOutputStream;
28 |
29 | import org.junit.Assert;
30 | import org.junit.Test;
31 |
32 | @SuppressWarnings("javadoc")
33 | public class SerializationTest extends DatabaseTestBase
34 | {
35 |
36 | @Test
37 | public void serializationCheckPGgeometry() throws Exception
38 | {
39 | if (!hasDatabase())
40 | {
41 | return;
42 | }
43 | try
44 | {
45 | new ObjectOutputStream(new ByteArrayOutputStream())
46 | .writeObject(new PGgeometry(getWKBFromWKT("MULTIPOLYGON(((1 1,1 2,2 1,1 1)))")));
47 | }
48 | catch (NotSerializableException ex)
49 | {
50 | Assert.fail("serialization of PGgeometry failed: " + ex);
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/ServerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Connection;
26 | import java.sql.DatabaseMetaData;
27 | import java.sql.ResultSet;
28 | import java.sql.SQLException;
29 | import java.sql.Statement;
30 | import java.util.UUID;
31 |
32 | import org.junit.Test;
33 | import org.slf4j.Logger;
34 | import org.slf4j.LoggerFactory;
35 |
36 | @SuppressWarnings("javadoc")
37 | public class ServerTest extends DatabaseTestBase
38 | {
39 |
40 | private static final String DATABASE_TABLE_NAME_PREFIX = "jdbc_test";
41 | private static final Logger logger = LoggerFactory.getLogger(ServerTest.class);
42 | private Connection connection = null;
43 | private Statement statement = null;
44 |
45 | /*
46 | * (non-Javadoc)
47 | * @see io.github.sebasbaumh.postgis.DatabaseTest#afterDatabaseSetup()
48 | */
49 | @Override
50 | protected void afterDatabaseSetup() throws SQLException
51 | {
52 | connection = getConnection();
53 | statement = connection.createStatement();
54 | }
55 |
56 | /*
57 | * (non-Javadoc)
58 | * @see io.github.sebasbaumh.postgis.DatabaseTest#beforeDatabaseShutdown()
59 | */
60 | @Override
61 | protected void beforeDatabaseShutdown() throws SQLException
62 | {
63 | if ((statement != null) && (!statement.isClosed()))
64 | {
65 | statement.close();
66 | }
67 | if ((connection != null) && (!connection.isClosed()))
68 | {
69 | connection.close();
70 | }
71 | }
72 |
73 | @Test
74 | public void testServer() throws Exception
75 | {
76 | if (!hasDatabase())
77 | {
78 | return;
79 | }
80 |
81 | String dbtable = DATABASE_TABLE_NAME_PREFIX + "_"
82 | + UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
83 |
84 | String dropSQL = "drop table " + dbtable;
85 | String createSQL = "create table " + dbtable + " (geom geometry, id int4)";
86 | String insertPointSQL = "insert into " + dbtable + " values ('POINT (10 10 10)',1)";
87 | String insertPolygonSQL = "insert into " + dbtable
88 | + " values ('POLYGON ((0 0 0,0 10 0,10 10 0,10 0 0,0 0 0))',2)";
89 |
90 | logger.debug("Adding geometric type entries...");
91 | ((org.postgresql.PGConnection) connection).addDataType("geometry", PGgeometry.class);
92 | ((org.postgresql.PGConnection) connection).addDataType("box2d", PGbox2d.class);
93 | ((org.postgresql.PGConnection) connection).addDataType("box3d", PGbox3d.class);
94 |
95 | logger.debug("Creating table with geometric types...");
96 | boolean tableExists = false;
97 | DatabaseMetaData databaseMetaData = connection.getMetaData();
98 | try (ResultSet resultSet = databaseMetaData.getTables(null, null, dbtable, new String[] { "TABLE" }))
99 | {
100 | while (resultSet.next())
101 | {
102 | tableExists = true;
103 | break;
104 | }
105 | }
106 | if (tableExists)
107 | {
108 | statement.execute(dropSQL);
109 | }
110 | statement.execute(createSQL);
111 | try
112 | {
113 | logger.debug("Inserting point...");
114 | statement.execute(insertPointSQL);
115 |
116 | logger.debug("Inserting polygon...");
117 | statement.execute(insertPolygonSQL);
118 |
119 | logger.debug("Querying table...");
120 | try (ResultSet resultSet = statement.executeQuery("select ST_AsText(geom),id from " + dbtable))
121 | {
122 | while (resultSet.next())
123 | {
124 | Object obj = resultSet.getObject(1);
125 | int id = resultSet.getInt(2);
126 | logger.debug("Row {}: {}", id, obj);
127 | }
128 | }
129 | }
130 | finally
131 | {
132 | // make sure to remove the table afterwards
133 | statement.execute(dropSQL);
134 | }
135 | }
136 |
137 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/ServiceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Driver;
26 | import java.sql.DriverManager;
27 | import java.sql.SQLException;
28 |
29 | import org.junit.Assert;
30 | import org.junit.Test;
31 |
32 | /**
33 | * Tests to ensure that the drivers that are registered as services in META-INF/services/java.sql.Driver are resolved
34 | * correctly. Ported from postgis-java.
35 | */
36 | @SuppressWarnings({ "static-method", "javadoc" })
37 | public class ServiceTest
38 | {
39 |
40 | @Test
41 | public void testWrapperService() throws SQLException
42 | {
43 | String jdbcUrl = System.getProperty(DatabaseTestBase.CONFIG_JDBC_URL);
44 | if (jdbcUrl == null)
45 | {
46 | System.out.println("Tests are running without a database");
47 | return;
48 | }
49 |
50 | if (jdbcUrl.startsWith(DriverWrapper.POSTGRES_PROTOCOL))
51 | {
52 | jdbcUrl = DriverWrapper.POSTGIS_PROTOCOL + jdbcUrl.substring(DriverWrapper.POSTGRES_PROTOCOL.length());
53 | }
54 | else
55 | {
56 | throw new SQLException("Unknown protocol or subprotocol in url: " + jdbcUrl);
57 | }
58 | Driver driver = DriverManager.getDriver(jdbcUrl);
59 | Assert.assertEquals(DriverWrapper.class, driver.getClass());
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/TokenizerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.util.List;
26 |
27 | import org.junit.Test;
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | @SuppressWarnings({ "static-method", "javadoc" })
32 | public class TokenizerTest
33 | {
34 |
35 | private static final Logger logger = LoggerFactory.getLogger(TokenizerTest.class);
36 |
37 | @Test
38 | public void testTokenizer()
39 | {
40 | char delimiterL1 = ',';
41 | char delimiterL2 = ' ';
42 | String stringToTokenize = "((1 2 3),(4 5 6),(7 8 9)";
43 | logger.debug("tokenizing string value => {}", stringToTokenize);
44 | List tokensLevel1 = PostGisUtil.split(PostGisUtil.removeBrackets(stringToTokenize), delimiterL1);
45 | logger.debug("level 1 tokens [delimiter = {}] [tokenCount = {}]", delimiterL1, tokensLevel1.size());
46 | for (String tokenL1 : tokensLevel1)
47 | {
48 | logger.debug("L1 token => {} / {}", tokenL1, PostGisUtil.removeBrackets(tokenL1));
49 | List tokensLevel2 = PostGisUtil.split(PostGisUtil.removeBrackets(tokenL1), delimiterL2);
50 | logger.debug("level 2 tokens [delimiter = {}] [tokenCount = {}]", delimiterL2, tokensLevel2.size());
51 | for (String tokenL2 : tokensLevel2)
52 | {
53 | logger.debug("L2 token => {} / {}", tokenL2, PostGisUtil.removeBrackets(tokenL2));
54 | }
55 | }
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/sebasbaumh/postgis/VersionPrinterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * PostGIS extension for PostgreSQL JDBC driver
3 | *
4 | * (C) 2004 Paul Ramsey, pramsey@refractions.net
5 | * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
6 | * (C) 2015 Phillip Ross, phillip.w.g.ross@gmail.com
7 | * (C) 2018-2023 Sebastian Baumhekel, sebastian.baumhekel@gmail.com
8 | *
9 | * This library is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * This library is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with this library. If not, see .
21 | */
22 |
23 | package io.github.sebasbaumh.postgis;
24 |
25 | import java.sql.Connection;
26 | import java.sql.ResultSet;
27 | import java.sql.SQLException;
28 | import java.sql.Statement;
29 |
30 | import org.junit.Assert;
31 | import org.junit.Test;
32 | import org.postgresql.Driver;
33 | import org.postgresql.util.PSQLState;
34 | import org.slf4j.Logger;
35 | import org.slf4j.LoggerFactory;
36 |
37 | /**
38 | * Prints out as much version information as available.
39 | */
40 | @SuppressWarnings("javadoc")
41 | public class VersionPrinterTest extends DatabaseTestBase
42 | {
43 |
44 | private static final Logger logger = LoggerFactory.getLogger(VersionPrinterTest.class);
45 |
46 | private static final String[] POSTGIS_FUNCTIONS = { "postgis_version", "postgis_proj_version",
47 | "postgis_scripts_installed", "postgis_lib_version", "postgis_scripts_released", "postgis_uses_stats",
48 | "postgis_geos_version", "postgis_scripts_build_date", "postgis_lib_build_date", "postgis_full_version",
49 | "postgis_gdal_version", "postgis_libjson_version", "postgis_libxml_version", "postgis_raster_lib_version",
50 | "postgis_svn_version" };
51 |
52 | private Connection connection = null;
53 | private Statement statement = null;
54 |
55 | /*
56 | * (non-Javadoc)
57 | * @see io.github.sebasbaumh.postgis.DatabaseTest#afterDatabaseSetup()
58 | */
59 | @Override
60 | protected void afterDatabaseSetup() throws SQLException
61 | {
62 | connection = getConnection();
63 | statement = connection.createStatement();
64 | }
65 |
66 | /*
67 | * (non-Javadoc)
68 | * @see io.github.sebasbaumh.postgis.DatabaseTest#beforeDatabaseShutdown()
69 | */
70 | @Override
71 | protected void beforeDatabaseShutdown() throws SQLException
72 | {
73 | if ((statement != null) && (!statement.isClosed()))
74 | {
75 | statement.close();
76 | }
77 | if ((connection != null) && (!connection.isClosed()))
78 | {
79 | connection.close();
80 | }
81 | }
82 |
83 | private String getVersionString(String function) throws SQLException
84 | {
85 | String result = "-- unavailable -- ";
86 | try
87 | {
88 | try (ResultSet resultSet = statement.executeQuery("SELECT " + function + "()"))
89 | {
90 | if (resultSet.next())
91 | {
92 | String version = resultSet.getString(1);
93 | if (version != null)
94 | {
95 | result = version.trim();
96 | }
97 | else
98 | {
99 | result = "-- null result --";
100 | }
101 | }
102 | else
103 | {
104 | result = "-- no result --";
105 | }
106 | }
107 | }
108 | catch (SQLException sqle)
109 | {
110 | // If the function does not exist, a SQLException will be thrown, but it should be caught an swallowed if
111 | // the "does not exist" string is in the error message. The SQLException might be thrown for some other
112 | // problem not related to the missing function, so rethrow it if it doesn't contain the string.
113 | if (!PSQLState.UNDEFINED_FUNCTION.getState().equals(sqle.getSQLState()))
114 | {
115 | throw sqle;
116 | }
117 | }
118 | return result;
119 | }
120 |
121 | @Test
122 | @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("CRLF_INJECTION_LOGS")
123 | public void test() throws Exception
124 | {
125 | if (!hasDatabase())
126 | {
127 | return;
128 | }
129 |
130 | // Print PostGIS version
131 | logger.info("*** PostGIS jdbc client code ***");
132 | // Print PostgreSQL JDBC Versions
133 | logger.info("*** PostgreSQL JDBC Driver ***");
134 | @SuppressWarnings("deprecation")
135 | String driverVersion = Driver.getVersion();
136 | Assert.assertNotNull(driverVersion);
137 | logger.info("\t getVersion: {}", driverVersion);
138 |
139 | try
140 | {
141 | Driver driver = new Driver();
142 | int majorVersion = driver.getMajorVersion();
143 | Assert.assertNotEquals(majorVersion, 0);
144 | logger.info("\t getMajorVersion: {}", majorVersion);
145 | int minorVersion = driver.getMinorVersion();
146 | Assert.assertNotEquals(minorVersion, 0);
147 | logger.info("\t getMinorVersion: {}", majorVersion);
148 | }
149 | catch (Exception e)
150 | {
151 | logger.error("Cannot create Driver instance: {}", e.getMessage());
152 | }
153 |
154 | // Print PostgreSQL server versions
155 | Assert.assertNotNull(connection);
156 | logger.info("*** PostgreSQL Server ***");
157 | String versionString = getVersionString("version");
158 | logger.info("\t version: {}", versionString);
159 |
160 | // Print PostGIS versions
161 | logger.info("*** PostGIS Server ***");
162 | for (String GISVERSION : POSTGIS_FUNCTIONS)
163 | {
164 | versionString = getVersionString(GISVERSION);
165 | logger.info("\t {} version: {}", GISVERSION, versionString);
166 | }
167 | }
168 |
169 | }
--------------------------------------------------------------------------------