aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2020-08-05 20:53:53 +0100
committerNeil Fuller <nfuller@google.com>2020-08-05 20:53:53 +0100
commit2431afb27465e3663dbb545f1f46344367809649 (patch)
tree65054c253fdd75105b9ea0f26d5d55ca665f5c8a
parentcfd5e8ffb76c3bc3cf83a69eee64deadb5672f2d (diff)
parentb02f8a3a10c09fe673aaf3530ec640cb8e80bebb (diff)
downloadgeojson-jackson-2431afb27465e3663dbb545f1f46344367809649.tar.gz
Merge tag 'upstream/upstream-geojson-jackson-1.14'
[maven-release-plugin] copy for tag geojson-jackson-1.14 Initial import into Android of geojson-jackson-1.14 tag. Test: None Bug: 152747091 Change-Id: I3d1fdfbcb64700cb8f8ad4987c45801bec53130c
-rw-r--r--.gitignore7
-rw-r--r--LICENSE191
-rw-r--r--README.md59
-rw-r--r--pom.xml124
-rw-r--r--src/main/java/org/geojson/Crs.java56
-rw-r--r--src/main/java/org/geojson/Feature.java81
-rw-r--r--src/main/java/org/geojson/FeatureCollection.java58
-rw-r--r--src/main/java/org/geojson/GeoJsonObject.java63
-rw-r--r--src/main/java/org/geojson/GeoJsonObjectVisitor.java83
-rw-r--r--src/main/java/org/geojson/Geometry.java59
-rw-r--r--src/main/java/org/geojson/GeometryCollection.java57
-rw-r--r--src/main/java/org/geojson/LineString.java21
-rw-r--r--src/main/java/org/geojson/LngLatAlt.java164
-rw-r--r--src/main/java/org/geojson/MultiLineString.java23
-rw-r--r--src/main/java/org/geojson/MultiPoint.java21
-rw-r--r--src/main/java/org/geojson/MultiPolygon.java28
-rw-r--r--src/main/java/org/geojson/Point.java65
-rw-r--r--src/main/java/org/geojson/Polygon.java70
-rw-r--r--src/main/java/org/geojson/jackson/CrsType.java5
-rw-r--r--src/main/java/org/geojson/jackson/LngLatAltDeserializer.java69
-rw-r--r--src/main/java/org/geojson/jackson/LngLatAltSerializer.java27
-rw-r--r--src/test/java/org/geojson/FeatureTest.java27
-rw-r--r--src/test/java/org/geojson/GeoJsonObjectVisitorTest.java95
-rw-r--r--src/test/java/org/geojson/LngLatAltTest.java184
-rw-r--r--src/test/java/org/geojson/ToStringTest.java97
-rw-r--r--src/test/java/org/geojson/jackson/CrsTest.java34
-rw-r--r--src/test/java/org/geojson/jackson/GeoJsonObjectTest.java19
-rw-r--r--src/test/java/org/geojson/jackson/GeometryCollectionTest.java57
-rw-r--r--src/test/java/org/geojson/jackson/LineStringTest.java34
-rw-r--r--src/test/java/org/geojson/jackson/LngLatAltDeserializerTest.java21
-rw-r--r--src/test/java/org/geojson/jackson/LngLatAltSerializerTest.java20
-rw-r--r--src/test/java/org/geojson/jackson/MockData.java14
-rw-r--r--src/test/java/org/geojson/jackson/MultiLineStringTest.java24
-rw-r--r--src/test/java/org/geojson/jackson/MultiPointTest.java34
-rw-r--r--src/test/java/org/geojson/jackson/MultiPoligonTest.java38
-rw-r--r--src/test/java/org/geojson/jackson/PointTest.java89
-rw-r--r--src/test/java/org/geojson/jackson/PolygonTest.java74
37 files changed, 2192 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..98d2973
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+target
+
+.project
+.classpath
+.settings
+*.iml
+.idea
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..37ec93a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..52ff551
--- /dev/null
+++ b/README.md
@@ -0,0 +1,59 @@
+GeoJson POJOs for Jackson
+=========================
+
+A small package of all GeoJson POJOs (Plain Old Java Objects) for serializing and
+deserializing of objects via JSON Jackson Parser.
+
+Usage
+-----
+
+If you know what kind of object you expect from a GeoJson file you can directly read it like this:
+
+
+```java
+FeatureCollection featureCollection =
+ new ObjectMapper().readValue(inputStream, FeatureCollection.class);
+```
+
+If you want to read any GeoJson file read the value as GeoJsonObject and then test for the contents via instanceOf:
+
+```java
+GeoJsonObject object = new ObjectMapper().readValue(inputStream, GeoJsonObject.class);
+if (object instanceof Polygon) {
+ ...
+} else if (object instanceof Feature) {
+ ...
+}
+```
+and so on.
+
+Or you can use the GeoJsonObjectVisitor to visit the right method:
+
+```java
+GeoJsonObject object = new ObjectMapper().readValue(inputStream, GeoJsonObject.class);
+object.accept(visitor);
+```
+
+
+Writing Json is even easier. You just have to create the GeoJson objects and pass them to the Jackson ObjectMapper.
+
+```java
+FeatureCollection featureCollection = new FeatureCollection();
+featureCollection.add(new Feature());
+
+String json= new ObjectMapper().writeValueAsString(featureCollection);
+```
+
+Maven Central
+-------------
+
+You can find the library in the Maven Central Repository.
+
+```xml
+<dependency>
+ <groupId>de.grundid.opendatalab</groupId>
+ <artifactId>geojson-jackson</artifactId>
+ <version>1.8.1</version>
+</dependency>
+```
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5c756cd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.sonatype.oss</groupId>
+ <artifactId>oss-parent</artifactId>
+ <version>7</version>
+ </parent>
+
+ <groupId>de.grundid.opendatalab</groupId>
+ <artifactId>geojson-jackson</artifactId>
+ <version>1.14</version>
+ <packaging>jar</packaging>
+
+
+ <name>GeoJson POJOs for Jackson </name>
+ <url>https://github.com/opendatalab-de/geojson-jackson</url>
+ <description>A collection of Java POJOs for GeoJson</description>
+
+ <scm>
+ <connection>scm:git:git://github.com/opendatalab-de/geojson-jackson.git</connection>
+ <developerConnection>scm:git:ssh://git@github.com:/opendatalab-de/geojson-jackson.git</developerConnection>
+ <tag>geojson-jackson-1.14</tag>
+ </scm>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <name>Adrian Stabiszewski</name>
+ <email>as@nfctools.org</email>
+ <organization>GrundID GmbH</organization>
+ <organizationUrl>http://www.grundid.de</organizationUrl>
+ </developer>
+ </developers>
+
+ <properties>
+ <java-version>1.6</java-version>
+ <jackson-version>2.10.0</jackson-version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>2.2</version>
+ </extension>
+ </extensions>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.5.1</version>
+ <inherited>true</inherited>
+ <configuration>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
+ <arguments>-Psonatype-oss-release -Dgpg.passphrase=</arguments>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>${java-version}</source>
+ <target>${java-version}</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/src/main/java/org/geojson/Crs.java b/src/main/java/org/geojson/Crs.java
new file mode 100644
index 0000000..9aa203c
--- /dev/null
+++ b/src/main/java/org/geojson/Crs.java
@@ -0,0 +1,56 @@
+package org.geojson;
+
+import org.geojson.jackson.CrsType;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Crs implements Serializable{
+
+ private CrsType type = CrsType.name;
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ public CrsType getType() {
+ return type;
+ }
+
+ public void setType(CrsType type) {
+ this.type = type;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Crs)) {
+ return false;
+ }
+ Crs crs = (Crs)o;
+ if (properties != null ? !properties.equals(crs.properties) : crs.properties != null) {
+ return false;
+ }
+ return !(type != null ? !type.equals(crs.type) : crs.type != null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Crs{" + "type='" + type + '\'' + ", properties=" + properties + '}';
+ }
+}
diff --git a/src/main/java/org/geojson/Feature.java b/src/main/java/org/geojson/Feature.java
new file mode 100644
index 0000000..1d9c7fe
--- /dev/null
+++ b/src/main/java/org/geojson/Feature.java
@@ -0,0 +1,81 @@
+package org.geojson;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Feature extends GeoJsonObject {
+
+ @JsonInclude(JsonInclude.Include.ALWAYS)
+ private Map<String, Object> properties = new HashMap<String, Object>();
+ @JsonInclude(JsonInclude.Include.ALWAYS)
+ private GeoJsonObject geometry;
+ private String id;
+
+ public void setProperty(String key, Object value) {
+ properties.put(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getProperty(String key) {
+ return (T)properties.get(key);
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public GeoJsonObject getGeometry() {
+ return geometry;
+ }
+
+ public void setGeometry(GeoJsonObject geometry) {
+ this.geometry = geometry;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ if (!super.equals(o))
+ return false;
+ Feature feature = (Feature)o;
+ if (properties != null ? !properties.equals(feature.properties) : feature.properties != null)
+ return false;
+ if (geometry != null ? !geometry.equals(feature.geometry) : feature.geometry != null)
+ return false;
+ return !(id != null ? !id.equals(feature.id) : feature.id != null);
+ }
+
+ @Override public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ result = 31 * result + (geometry != null ? geometry.hashCode() : 0);
+ result = 31 * result + (id != null ? id.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Feature{properties=" + properties + ", geometry=" + geometry + ", id='" + id + "'}";
+ }
+}
diff --git a/src/main/java/org/geojson/FeatureCollection.java b/src/main/java/org/geojson/FeatureCollection.java
new file mode 100644
index 0000000..ecde9bd
--- /dev/null
+++ b/src/main/java/org/geojson/FeatureCollection.java
@@ -0,0 +1,58 @@
+package org.geojson;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+public class FeatureCollection extends GeoJsonObject implements Iterable<Feature> {
+
+ private List<Feature> features = new ArrayList<Feature>();
+
+ public List<Feature> getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List<Feature> features) {
+ this.features = features;
+ }
+
+ public FeatureCollection add(Feature feature) {
+ features.add(feature);
+ return this;
+ }
+
+ public void addAll(Collection<Feature> features) {
+ this.features.addAll(features);
+ }
+
+ @Override
+ public Iterator<Feature> iterator() {
+ return features.iterator();
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof FeatureCollection))
+ return false;
+ FeatureCollection features1 = (FeatureCollection)o;
+ return features.equals(features1.features);
+ }
+
+ @Override
+ public int hashCode() {
+ return features.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "FeatureCollection{" + "features=" + features + '}';
+ }
+}
diff --git a/src/main/java/org/geojson/GeoJsonObject.java b/src/main/java/org/geojson/GeoJsonObject.java
new file mode 100644
index 0000000..ed045f2
--- /dev/null
+++ b/src/main/java/org/geojson/GeoJsonObject.java
@@ -0,0 +1,63 @@
+package org.geojson;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+
+@JsonTypeInfo(property = "type", use = Id.NAME)
+@JsonSubTypes({ @Type(Feature.class), @Type(Polygon.class), @Type(MultiPolygon.class), @Type(FeatureCollection.class),
+ @Type(Point.class), @Type(MultiPoint.class), @Type(MultiLineString.class), @Type(LineString.class),
+ @Type(GeometryCollection.class) })
+@JsonInclude(Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public abstract class GeoJsonObject implements Serializable {
+
+ private Crs crs;
+ private double[] bbox;
+ public Crs getCrs() {
+ return crs;
+ }
+
+ public void setCrs(Crs crs) {
+ this.crs = crs;
+ }
+
+ public double[] getBbox() {
+ return bbox;
+ }
+
+ public void setBbox(double[] bbox) {
+ this.bbox = bbox;
+ }
+
+ public abstract <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor);
+
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ GeoJsonObject that = (GeoJsonObject)o;
+ if (crs != null ? !crs.equals(that.crs) : that.crs != null)
+ return false;
+ return Arrays.equals(bbox, that.bbox);
+ }
+
+ @Override public int hashCode() {
+ int result = crs != null ? crs.hashCode() : 0;
+ result = 31 * result + (bbox != null ? Arrays.hashCode(bbox) : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoJsonObject{}";
+ }
+}
diff --git a/src/main/java/org/geojson/GeoJsonObjectVisitor.java b/src/main/java/org/geojson/GeoJsonObjectVisitor.java
new file mode 100644
index 0000000..8232d5e
--- /dev/null
+++ b/src/main/java/org/geojson/GeoJsonObjectVisitor.java
@@ -0,0 +1,83 @@
+package org.geojson;
+
+/**
+ * Visitor to handle all different types of {@link GeoJsonObject}.
+ *
+ * @param <T>
+ * return type of the visitor.
+ */
+public interface GeoJsonObjectVisitor<T> {
+
+ T visit(GeometryCollection geoJsonObject);
+
+ T visit(FeatureCollection geoJsonObject);
+
+ T visit(Point geoJsonObject);
+
+ T visit(Feature geoJsonObject);
+
+ T visit(MultiLineString geoJsonObject);
+
+ T visit(Polygon geoJsonObject);
+
+ T visit(MultiPolygon geoJsonObject);
+
+ T visit(MultiPoint geoJsonObject);
+
+ T visit(LineString geoJsonObject);
+
+ /**
+ * An abstract adapter class for visiting GeoJson objects.
+ * The methods in this class are empty.
+ * This class exists as convenience for creating listener objects.
+ *
+ * @param <T> Return type of the visitor
+ */
+ class Adapter<T> implements GeoJsonObjectVisitor<T> {
+
+ @Override
+ public T visit(GeometryCollection geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(FeatureCollection geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(Point geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(Feature geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(MultiLineString geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(Polygon geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(MultiPolygon geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(MultiPoint geoJsonObject) {
+ return null;
+ }
+
+ @Override
+ public T visit(LineString geoJsonObject) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/geojson/Geometry.java b/src/main/java/org/geojson/Geometry.java
new file mode 100644
index 0000000..2f65fcd
--- /dev/null
+++ b/src/main/java/org/geojson/Geometry.java
@@ -0,0 +1,59 @@
+package org.geojson;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class Geometry<T> extends GeoJsonObject {
+
+ protected List<T> coordinates = new ArrayList<T>();
+
+ public Geometry() {
+ }
+
+ public Geometry(T... elements) {
+ for (T coordinate : elements) {
+ coordinates.add(coordinate);
+ }
+ }
+
+ public Geometry<T> add(T elements) {
+ coordinates.add(elements);
+ return this;
+ }
+
+ public List<T> getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(List<T> coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Geometry)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ Geometry geometry = (Geometry)o;
+ return !(coordinates != null ? !coordinates.equals(geometry.coordinates) : geometry.coordinates != null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (coordinates != null ? coordinates.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Geometry{" + "coordinates=" + coordinates + "} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/GeometryCollection.java b/src/main/java/org/geojson/GeometryCollection.java
new file mode 100644
index 0000000..b7fc809
--- /dev/null
+++ b/src/main/java/org/geojson/GeometryCollection.java
@@ -0,0 +1,57 @@
+package org.geojson;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class GeometryCollection extends GeoJsonObject implements Iterable<GeoJsonObject> {
+
+ private List<GeoJsonObject> geometries = new ArrayList<GeoJsonObject>();
+
+ public List<GeoJsonObject> getGeometries() {
+ return geometries;
+ }
+
+ public void setGeometries(List<GeoJsonObject> geometries) {
+ this.geometries = geometries;
+ }
+
+ @Override
+ public Iterator<GeoJsonObject> iterator() {
+ return geometries.iterator();
+ }
+
+ public GeometryCollection add(GeoJsonObject geometry) {
+ geometries.add(geometry);
+ return this;
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof GeometryCollection))
+ return false;
+ if (!super.equals(o))
+ return false;
+ GeometryCollection that = (GeometryCollection)o;
+ return !(geometries != null ? !geometries.equals(that.geometries) : that.geometries != null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (geometries != null ? geometries.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeometryCollection{" + "geometries=" + geometries + "} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/LineString.java b/src/main/java/org/geojson/LineString.java
new file mode 100644
index 0000000..144be96
--- /dev/null
+++ b/src/main/java/org/geojson/LineString.java
@@ -0,0 +1,21 @@
+package org.geojson;
+
+public class LineString extends MultiPoint {
+
+ public LineString() {
+ }
+
+ public LineString(LngLatAlt... points) {
+ super(points);
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return "LineString{} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/LngLatAlt.java b/src/main/java/org/geojson/LngLatAlt.java
new file mode 100644
index 0000000..0ffa8ac
--- /dev/null
+++ b/src/main/java/org/geojson/LngLatAlt.java
@@ -0,0 +1,164 @@
+package org.geojson;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.geojson.jackson.LngLatAltDeserializer;
+import org.geojson.jackson.LngLatAltSerializer;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+@JsonDeserialize(using = LngLatAltDeserializer.class)
+@JsonSerialize(using = LngLatAltSerializer.class)
+public class LngLatAlt implements Serializable{
+
+ private double longitude;
+ private double latitude;
+ private double altitude = Double.NaN;
+ private double[] additionalElements = new double[0];
+
+ public LngLatAlt() {
+ }
+
+ public LngLatAlt(double longitude, double latitude) {
+ this.longitude = longitude;
+ this.latitude = latitude;
+ }
+
+ public LngLatAlt(double longitude, double latitude, double altitude) {
+ this.longitude = longitude;
+ this.latitude = latitude;
+ this.altitude = altitude;
+ }
+
+ /**
+ * Construct a LngLatAlt with additional elements.
+ * The specification allows for any number of additional elements in a position, after lng, lat, alt.
+ * http://geojson.org/geojson-spec.html#positions
+ * @param longitude The longitude.
+ * @param latitude The latitude.
+ * @param altitude The altitude.
+ * @param additionalElements The additional elements.
+ */
+ public LngLatAlt(double longitude, double latitude, double altitude, double... additionalElements) {
+ this.longitude = longitude;
+ this.latitude = latitude;
+ this.altitude = altitude;
+
+ setAdditionalElements(additionalElements);
+ checkAltitudeAndAdditionalElements();
+ }
+
+ public boolean hasAltitude() {
+ return !Double.isNaN(altitude);
+ }
+
+ public boolean hasAdditionalElements() {
+ return additionalElements.length > 0;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public double getAltitude() {
+ return altitude;
+ }
+
+ public void setAltitude(double altitude) {
+ this.altitude = altitude;
+ checkAltitudeAndAdditionalElements();
+ }
+
+ public double[] getAdditionalElements() {
+ return additionalElements;
+ }
+
+ public void setAdditionalElements(double... additionalElements) {
+ if (additionalElements != null) {
+ this.additionalElements = additionalElements;
+ } else {
+ this.additionalElements = new double[0];
+ }
+
+ for(double element : this.additionalElements) {
+ if (Double.isNaN(element)) {
+ throw new IllegalArgumentException("No additional elements may be NaN.");
+ }
+ if (Double.isInfinite(element)) {
+ throw new IllegalArgumentException("No additional elements may be infinite.");
+ }
+ }
+
+ checkAltitudeAndAdditionalElements();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof LngLatAlt)) {
+ return false;
+ }
+ LngLatAlt lngLatAlt = (LngLatAlt)o;
+ return Double.compare(lngLatAlt.latitude, latitude) == 0 && Double.compare(lngLatAlt.longitude, longitude) == 0
+ && Double.compare(lngLatAlt.altitude, altitude) == 0 &&
+ Arrays.equals(lngLatAlt.getAdditionalElements(), additionalElements);
+ }
+
+ @Override
+ public int hashCode() {
+ long temp = Double.doubleToLongBits(longitude);
+ int result = (int)(temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(latitude);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(altitude);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+ for(double element : additionalElements) {
+ temp = Double.doubleToLongBits(element);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ String s = "LngLatAlt{" + "longitude=" + longitude + ", latitude=" + latitude + ", altitude=" + altitude;
+
+ if (hasAdditionalElements()) {
+ s += ", additionalElements=[";
+
+ String suffix = "";
+ for (Double element : additionalElements) {
+ if (element != null) {
+ s += suffix + element;
+ suffix = ", ";
+ }
+ }
+ s += ']';
+ }
+
+ s += '}';
+
+ return s;
+ }
+
+ private void checkAltitudeAndAdditionalElements() {
+ if (!hasAltitude() && hasAdditionalElements()) {
+ throw new IllegalArgumentException("Additional Elements are only valid if Altitude is also provided.");
+ }
+ }
+}
diff --git a/src/main/java/org/geojson/MultiLineString.java b/src/main/java/org/geojson/MultiLineString.java
new file mode 100644
index 0000000..4d32c77
--- /dev/null
+++ b/src/main/java/org/geojson/MultiLineString.java
@@ -0,0 +1,23 @@
+package org.geojson;
+
+import java.util.List;
+
+public class MultiLineString extends Geometry<List<LngLatAlt>> {
+
+ public MultiLineString() {
+ }
+
+ public MultiLineString(List<LngLatAlt> line) {
+ add(line);
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return "MultiLineString{} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/MultiPoint.java b/src/main/java/org/geojson/MultiPoint.java
new file mode 100644
index 0000000..b022ec0
--- /dev/null
+++ b/src/main/java/org/geojson/MultiPoint.java
@@ -0,0 +1,21 @@
+package org.geojson;
+
+public class MultiPoint extends Geometry<LngLatAlt> {
+
+ public MultiPoint() {
+ }
+
+ public MultiPoint(LngLatAlt... points) {
+ super(points);
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return "MultiPoint{} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/MultiPolygon.java b/src/main/java/org/geojson/MultiPolygon.java
new file mode 100644
index 0000000..9698c2f
--- /dev/null
+++ b/src/main/java/org/geojson/MultiPolygon.java
@@ -0,0 +1,28 @@
+package org.geojson;
+
+import java.util.List;
+
+public class MultiPolygon extends Geometry<List<List<LngLatAlt>>> {
+
+ public MultiPolygon() {
+ }
+
+ public MultiPolygon(Polygon polygon) {
+ add(polygon);
+ }
+
+ public MultiPolygon add(Polygon polygon) {
+ coordinates.add(polygon.getCoordinates());
+ return this;
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return "MultiPolygon{} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/Point.java b/src/main/java/org/geojson/Point.java
new file mode 100644
index 0000000..3f4f349
--- /dev/null
+++ b/src/main/java/org/geojson/Point.java
@@ -0,0 +1,65 @@
+package org.geojson;
+
+public class Point extends GeoJsonObject {
+
+ private LngLatAlt coordinates;
+
+ public Point() {
+ }
+
+ public Point(LngLatAlt coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public Point(double longitude, double latitude) {
+ coordinates = new LngLatAlt(longitude, latitude);
+ }
+
+ public Point(double longitude, double latitude, double altitude) {
+ coordinates = new LngLatAlt(longitude, latitude, altitude);
+ }
+
+ public Point(double longitude, double latitude, double altitude, double... additionalElements) {
+ coordinates = new LngLatAlt(longitude, latitude, altitude, additionalElements);
+ }
+
+ public LngLatAlt getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(LngLatAlt coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Point)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ Point point = (Point)o;
+ return !(coordinates != null ? !coordinates.equals(point.coordinates) : point.coordinates != null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (coordinates != null ? coordinates.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Point{" + "coordinates=" + coordinates + "} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/Polygon.java b/src/main/java/org/geojson/Polygon.java
new file mode 100644
index 0000000..d4c42af
--- /dev/null
+++ b/src/main/java/org/geojson/Polygon.java
@@ -0,0 +1,70 @@
+package org.geojson;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class Polygon extends Geometry<List<LngLatAlt>> {
+
+ public Polygon() {
+ }
+
+ public Polygon(List<LngLatAlt> polygon) {
+ add(polygon);
+ }
+
+ public Polygon(LngLatAlt... polygon) {
+ add(Arrays.asList(polygon));
+ }
+
+ public void setExteriorRing(List<LngLatAlt> points) {
+ if (coordinates.isEmpty()) {
+ coordinates.add(0, points);
+ } else {
+ coordinates.set(0, points);
+ }
+ }
+
+ @JsonIgnore
+ public List<LngLatAlt> getExteriorRing() {
+ assertExteriorRing();
+ return coordinates.get(0);
+ }
+
+ @JsonIgnore
+ public List<List<LngLatAlt>> getInteriorRings() {
+ assertExteriorRing();
+ return coordinates.subList(1, coordinates.size());
+ }
+
+ public List<LngLatAlt> getInteriorRing(int index) {
+ assertExteriorRing();
+ return coordinates.get(1 + index);
+ }
+
+ public void addInteriorRing(List<LngLatAlt> points) {
+ assertExteriorRing();
+ coordinates.add(points);
+ }
+
+ public void addInteriorRing(LngLatAlt... points) {
+ assertExteriorRing();
+ coordinates.add(Arrays.asList(points));
+ }
+
+ private void assertExteriorRing() {
+ if (coordinates.isEmpty())
+ throw new RuntimeException("No exterior ring definied");
+ }
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ return geoJsonObjectVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return "Polygon{} " + super.toString();
+ }
+}
diff --git a/src/main/java/org/geojson/jackson/CrsType.java b/src/main/java/org/geojson/jackson/CrsType.java
new file mode 100644
index 0000000..2be1b21
--- /dev/null
+++ b/src/main/java/org/geojson/jackson/CrsType.java
@@ -0,0 +1,5 @@
+package org.geojson.jackson;
+
+public enum CrsType {
+ name, link;
+}
diff --git a/src/main/java/org/geojson/jackson/LngLatAltDeserializer.java b/src/main/java/org/geojson/jackson/LngLatAltDeserializer.java
new file mode 100644
index 0000000..ff888c6
--- /dev/null
+++ b/src/main/java/org/geojson/jackson/LngLatAltDeserializer.java
@@ -0,0 +1,69 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import org.geojson.LngLatAlt;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LngLatAltDeserializer extends JsonDeserializer<LngLatAlt> {
+
+ @Override
+ public LngLatAlt deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
+ if (jp.isExpectedStartArrayToken()) {
+ return deserializeArray(jp, ctxt);
+ }
+ throw ctxt.mappingException(LngLatAlt.class);
+ }
+
+ protected LngLatAlt deserializeArray(JsonParser jp, DeserializationContext ctxt) throws IOException {
+ LngLatAlt node = new LngLatAlt();
+ node.setLongitude(extractDouble(jp, ctxt, false));
+ node.setLatitude(extractDouble(jp, ctxt, false));
+ node.setAltitude(extractDouble(jp, ctxt, true));
+ List<Double> additionalElementsList = new ArrayList<Double>();
+ while (jp.hasCurrentToken() && jp.getCurrentToken() != JsonToken.END_ARRAY) {
+ double element = extractDouble(jp, ctxt, true);
+ if (!Double.isNaN(element)) {
+ additionalElementsList.add(element);
+ }
+ }
+ double[] additionalElements = new double[additionalElementsList.size()];
+ for (int i = 0; i < additionalElements.length; i++) {
+ additionalElements[i] = additionalElementsList.get(i);
+ }
+ node.setAdditionalElements(additionalElements);
+ return node;
+ }
+
+ private double extractDouble(JsonParser jp, DeserializationContext ctxt, boolean optional) throws IOException {
+ JsonToken token = jp.nextToken();
+ if (token == null) {
+ if (optional)
+ return Double.NaN;
+ else
+ throw ctxt.mappingException("Unexpected end-of-input when binding data into LngLatAlt");
+ } else {
+ switch (token) {
+ case END_ARRAY:
+ if (optional)
+ return Double.NaN;
+ else
+ throw ctxt.mappingException("Unexpected end-of-input when binding data into LngLatAlt");
+ case VALUE_NUMBER_FLOAT:
+ return jp.getDoubleValue();
+ case VALUE_NUMBER_INT:
+ return jp.getLongValue();
+ case VALUE_STRING:
+ return jp.getValueAsDouble();
+ default:
+ throw ctxt.mappingException(
+ "Unexpected token (" + token.name() + ") when binding data into LngLatAlt");
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/geojson/jackson/LngLatAltSerializer.java b/src/main/java/org/geojson/jackson/LngLatAltSerializer.java
new file mode 100644
index 0000000..a313d66
--- /dev/null
+++ b/src/main/java/org/geojson/jackson/LngLatAltSerializer.java
@@ -0,0 +1,27 @@
+package org.geojson.jackson;
+
+import java.io.IOException;
+
+import org.geojson.LngLatAlt;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+public class LngLatAltSerializer extends JsonSerializer<LngLatAlt> {
+
+ @Override
+ public void serialize(LngLatAlt value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ jgen.writeStartArray();
+ jgen.writeNumber(value.getLongitude());
+ jgen.writeNumber(value.getLatitude());
+ if (value.hasAltitude()) {
+ jgen.writeNumber(value.getAltitude());
+
+ for (double d : value.getAdditionalElements()) {
+ jgen.writeNumber(d);
+ }
+ }
+ jgen.writeEndArray();
+ }
+}
diff --git a/src/test/java/org/geojson/FeatureTest.java b/src/test/java/org/geojson/FeatureTest.java
new file mode 100644
index 0000000..6c69279
--- /dev/null
+++ b/src/test/java/org/geojson/FeatureTest.java
@@ -0,0 +1,27 @@
+package org.geojson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class FeatureTest {
+
+ private Feature testObject = new Feature();
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldHaveProperties() throws Exception {
+ assertNotNull(testObject.getProperties());
+ }
+
+ @Test
+ public void itShouldSerializeFeature() throws Exception {
+ // http://geojson.org/geojson-spec.html#feature-objects
+ // A feature object must have a member with the name "properties".
+ // The value of the properties member is an object (any JSON object or a JSON null value).
+ assertEquals("{\"type\":\"Feature\",\"properties\":{},\"geometry\":null}",
+ mapper.writeValueAsString(testObject));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/geojson/GeoJsonObjectVisitorTest.java b/src/test/java/org/geojson/GeoJsonObjectVisitorTest.java
new file mode 100644
index 0000000..1fca475
--- /dev/null
+++ b/src/test/java/org/geojson/GeoJsonObjectVisitorTest.java
@@ -0,0 +1,95 @@
+package org.geojson;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class GeoJsonObjectVisitorTest {
+
+ private final GeoJsonObject geoJsonObject;
+ private GeoJsonObjectVisitor<GeoJsonObject> instance = new GeoJsonObjectVisitor<GeoJsonObject>() {
+
+ @Override
+ public GeoJsonObject visit(GeometryCollection geoJsonObject) {
+ Assert.assertEquals(GeometryCollection.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(FeatureCollection geoJsonObject) {
+ Assert.assertEquals(FeatureCollection.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(Point geoJsonObject) {
+ Assert.assertEquals(Point.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(Feature geoJsonObject) {
+ Assert.assertEquals(Feature.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(MultiLineString geoJsonObject) {
+ Assert.assertEquals(MultiLineString.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(Polygon geoJsonObject) {
+ Assert.assertEquals(Polygon.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(MultiPolygon geoJsonObject) {
+ Assert.assertEquals(MultiPolygon.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(MultiPoint geoJsonObject) {
+ Assert.assertEquals(MultiPoint.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+
+ @Override
+ public GeoJsonObject visit(LineString geoJsonObject) {
+ Assert.assertEquals(LineString.class, geoJsonObject.getClass());
+ return geoJsonObject;
+ }
+ };
+ public GeoJsonObjectVisitorTest(GeoJsonObject geoJsonObject) {
+ this.geoJsonObject = geoJsonObject;
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] { { new GeometryCollection() }, { new FeatureCollection() },
+ { new Point(12D, 13D) }, { new Feature() },
+ { new MultiLineString(Arrays.asList(new LngLatAlt(12D, 13D))) }, { new Polygon() },
+ { new MultiPolygon() }, { new MultiPoint() }, { new LineString() } });
+ }
+
+ @Test
+ public void should_visit_right_class() {
+ // When
+ GeoJsonObject result = geoJsonObject.accept(this.instance);
+ // Then
+ Assert.assertEquals(geoJsonObject, result);
+ }
+
+ @Test
+ public void itShouldAdapter() throws Exception {
+ Assert.assertNull(geoJsonObject.accept(new GeoJsonObjectVisitor.Adapter<Void>()));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/geojson/LngLatAltTest.java b/src/test/java/org/geojson/LngLatAltTest.java
new file mode 100644
index 0000000..7045de7
--- /dev/null
+++ b/src/test/java/org/geojson/LngLatAltTest.java
@@ -0,0 +1,184 @@
+package org.geojson;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LngLatAltTest {
+
+ @Test
+ public void should_LngLatAlt_equals_without_alt() {
+ LngLatAlt first = new LngLatAlt(14.D, 13.D);
+ LngLatAlt second = new LngLatAlt(14.D, 13.D);
+ Assert.assertEquals(second, first);
+ }
+
+ @Test
+ public void should_LngLatAlt_equals_with_alt() {
+ LngLatAlt first = new LngLatAlt(14.D, 13.D, 15D);
+ LngLatAlt second = new LngLatAlt(14.D, 13.D, 15D);
+ Assert.assertEquals(second, first);
+ }
+
+ @Test
+ public void should_not_LngLatAlt_equals_with_alt() {
+ LngLatAlt first = new LngLatAlt(14.D, 13.D, 15D);
+ LngLatAlt second = new LngLatAlt(14.D, 13.D, 16D);
+ Assert.assertNotEquals(second, first);
+ }
+
+ @Test
+ public void should_not_LngLatAlt_equals_without_alt() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D);
+ LngLatAlt second = new LngLatAlt(14.D, 13.D, 16D);
+ Assert.assertNotEquals(second, first);
+ }
+
+ @Test
+ public void should_LngLatAlt_equals_with_additional_elements() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ LngLatAlt second = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ Assert.assertEquals(second, first);
+ Assert.assertEquals(second.hashCode(), first.hashCode());
+ }
+
+ @Test
+ public void should_LngLatAlt_equals_with_additional_elements_and_null() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ LngLatAlt second = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ Assert.assertEquals(second, first);
+ Assert.assertEquals(second.hashCode(), first.hashCode());
+ }
+
+ @Test
+ public void should_not_LngLatAlt_equals_without_additional_elements() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ LngLatAlt second = new LngLatAlt(14.D, 14.D, 15D);
+ Assert.assertNotEquals(second, first);
+ Assert.assertNotEquals(second.hashCode(), first.hashCode());
+ }
+
+ @Test
+ public void should_not_LngLatAlt_equals_with_additional_elements_in_different_order() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ LngLatAlt second = new LngLatAlt(14.D, 14.D, 15D, 17D, 16D);
+ Assert.assertNotEquals(second, first);
+ Assert.assertNotEquals(second.hashCode(), first.hashCode());
+ }
+
+ @Test
+ public void should_not_LngLatAlt_equals_with_additional_elements_and_different_size() {
+ LngLatAlt first = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D);
+ LngLatAlt second = new LngLatAlt(14.D, 14.D, 15D, 16D, 17D, 18D);
+ Assert.assertNotEquals(second, first);
+ Assert.assertNotEquals(second.hashCode(), first.hashCode());
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_alt_not_specified_in_constructor() {
+ try {
+ new LngLatAlt(14.D, 14.D, Double.NaN, 16D, 17D);
+ Assert.fail("Additional elements are not allowed if altitude is Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_alt_set_to_Nan_with_additional_elements() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D, 15.D, 16D, 17D);
+
+ try {
+ lngLatAlt.setAltitude(Double.NaN);
+ Assert.fail("Additional elements are not allowed if altitude is Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_additional_elements_set_with_missing_alt() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D);
+
+ try {
+ lngLatAlt.setAdditionalElements(42);
+ Assert.fail("Additional elements are not allowed if altitude is Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_additional_elements_set_with_Nan_alt() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D, Double.NaN);
+
+ try {
+ lngLatAlt.setAdditionalElements(42);
+ Assert.fail("Additional elements are not allowed if altitude is Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_constructed_to_Nan() {
+ try {
+ new LngLatAlt(14.D, 14.D, 15.D, 16.D, Double.NaN, 17.D);
+ Assert.fail("Additional elements are not allowed to be Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_constructed_to_Positive_Infinity() {
+ try {
+ new LngLatAlt(14.D, 14.D, 15.D, 16.D, Double.POSITIVE_INFINITY, 17.D);
+ Assert.fail("Additional elements are not allowed to be positive infinity.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_constructed_to_Negative_Infinity() {
+ try {
+ new LngLatAlt(14.D, 14.D, 15.D, 16.D, Double.NEGATIVE_INFINITY, 17.D);
+ Assert.fail("Additional elements are not allowed to be positive infinity.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_set_to_Nan() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D, 15.D);
+ try {
+ lngLatAlt.setAdditionalElements(16.D, Double.NaN, 17.D);
+ Assert.fail("Additional elements are not allowed to be Nan.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_set_to_Positive_Infinity() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D, 15.D);
+ try {
+ lngLatAlt.setAdditionalElements(16.D, Double.POSITIVE_INFINITY, 17.D);
+ Assert.fail("Additional elements are not allowed to be positive infinity.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+
+ @Test
+ public void should_LngLatAlt_throw_if_any_additional_elements_set_to_Negative_Infinity() {
+ LngLatAlt lngLatAlt = new LngLatAlt(14.D, 14.D, 15.D);
+ try {
+ lngLatAlt.setAdditionalElements(16.D, Double.NEGATIVE_INFINITY, 17.D);
+ Assert.fail("Additional elements are not allowed to be positive infinity.");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue("Expected exception.", true);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/geojson/ToStringTest.java b/src/test/java/org/geojson/ToStringTest.java
new file mode 100644
index 0000000..e892c5c
--- /dev/null
+++ b/src/test/java/org/geojson/ToStringTest.java
@@ -0,0 +1,97 @@
+package org.geojson;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+
+public class ToStringTest {
+
+ @Test
+ public void itShouldToStringCrs() throws Exception {
+ assertEquals("Crs{type='name', properties={}}", new Crs().toString());
+ }
+
+ @Test
+ public void itShouldToStringFeature() throws Exception {
+ assertEquals("Feature{properties={}, geometry=null, id='null'}", new Feature().toString());
+ }
+
+ @Test
+ public void itShouldToStringFeatureCollection() throws Exception {
+ assertEquals("FeatureCollection{features=[]}", new FeatureCollection().toString());
+ }
+
+ @Test
+ public void itShouldToStringPoint() throws Exception {
+ Point geometry = new Point(10, 20);
+ assertEquals(
+ "Point{coordinates=LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringPointWithAdditionalElements() {
+ Point geometry = new Point(10, 20, 30, 40D, 50D);
+ assertEquals(
+ "Point{coordinates=LngLatAlt{longitude=10.0, latitude=20.0, altitude=30.0, additionalElements=[40.0, 50.0]}} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringPointWithAdditionalElementsAndIgnoreNulls() {
+ Point geometry = new Point(10, 20, 30, 40D, 50D);
+ assertEquals(
+ "Point{coordinates=LngLatAlt{longitude=10.0, latitude=20.0, altitude=30.0, additionalElements=[40.0, 50.0]}} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringPolygon() throws Exception {
+ Polygon geometry = new Polygon(new LngLatAlt(10, 20), new LngLatAlt(30, 40), new LngLatAlt(10, 40),
+ new LngLatAlt(10, 20));
+ assertEquals(
+ "Polygon{} Geometry{coordinates=[[LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=30.0, latitude=40.0, altitude=NaN}, LngLatAlt{longitude=10.0, latitude=40.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}]]} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringMultiPolygon() throws Exception {
+ MultiPolygon geometry = new MultiPolygon(new Polygon(new LngLatAlt(10, 20), new LngLatAlt(30, 40),
+ new LngLatAlt(10, 40), new LngLatAlt(10, 20)));
+ geometry.add(new Polygon(new LngLatAlt(5, 20), new LngLatAlt(30, 40), new LngLatAlt(10, 40), new LngLatAlt(5,
+ 20)));
+ assertEquals("MultiPolygon{} Geometry{coordinates=[[[LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=30.0, latitude=40.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=10.0, latitude=40.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}]], "
+ + "[[LngLatAlt{longitude=5.0, latitude=20.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=30.0, latitude=40.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=10.0, latitude=40.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=5.0, latitude=20.0, altitude=NaN}]]]} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringLineString() throws Exception {
+ LineString geometry = new LineString(new LngLatAlt(49, 9), new LngLatAlt(41, 1));
+ assertEquals("LineString{} MultiPoint{} Geometry{coordinates=["
+ + "LngLatAlt{longitude=49.0, latitude=9.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=41.0, latitude=1.0, altitude=NaN}]} GeoJsonObject{}",
+ geometry.toString());
+ }
+
+ @Test
+ public void itShouldToStringMultiLineString() throws Exception {
+ MultiLineString geometry = new MultiLineString(Arrays.asList(new LngLatAlt(49, 9), new LngLatAlt(41, 1)));
+ geometry.add(Arrays.asList(new LngLatAlt(10, 20), new LngLatAlt(30, 40)));
+ assertEquals("MultiLineString{} Geometry{coordinates=[[LngLatAlt{longitude=49.0, latitude=9.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=41.0, latitude=1.0, altitude=NaN}], "
+ + "[LngLatAlt{longitude=10.0, latitude=20.0, altitude=NaN}, "
+ + "LngLatAlt{longitude=30.0, latitude=40.0, altitude=NaN}]]} GeoJsonObject{}",
+ geometry.toString());
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/CrsTest.java b/src/test/java/org/geojson/jackson/CrsTest.java
new file mode 100644
index 0000000..c845b50
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/CrsTest.java
@@ -0,0 +1,34 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.Crs;
+import org.geojson.GeoJsonObject;
+import org.geojson.Point;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CrsTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldParseCrsWithLink() throws Exception {
+ GeoJsonObject value = mapper.readValue("{\"crs\": { \"type\": \"link\", \"properties\": "
+ + "{ \"href\": \"http://example.com/crs/42\", \"type\": \"proj4\" }},"
+ + "\"type\":\"Point\",\"coordinates\":[100.0,5.0]}", GeoJsonObject.class);
+ assertNotNull(value);
+ assertEquals(CrsType.link, value.getCrs().getType());
+ }
+
+ @Test
+ public void itShouldSerializeCrsWithLink() throws Exception {
+ Point point = new Point();
+ Crs crs = new Crs();
+ crs.setType(CrsType.link);
+ point.setCrs(crs);
+ String value = mapper.writeValueAsString(point);
+ assertEquals("{\"type\":\"Point\",\"crs\":{\"type\":\"link\",\"properties\":{}}}", value);
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/GeoJsonObjectTest.java b/src/test/java/org/geojson/jackson/GeoJsonObjectTest.java
new file mode 100644
index 0000000..ed48428
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/GeoJsonObjectTest.java
@@ -0,0 +1,19 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.GeoJsonObject;
+import org.geojson.GeoJsonObjectVisitor;
+
+public class GeoJsonObjectTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+
+ private class TestGeoJsonObject extends GeoJsonObject {
+
+ @Override
+ public <T> T accept(GeoJsonObjectVisitor<T> geoJsonObjectVisitor) {
+ throw new RuntimeException("not implemented");
+ }
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/GeometryCollectionTest.java b/src/test/java/org/geojson/jackson/GeometryCollectionTest.java
new file mode 100644
index 0000000..02c743d
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/GeometryCollectionTest.java
@@ -0,0 +1,57 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.*;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class GeometryCollectionTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerialize() throws Exception {
+ GeometryCollection gc = new GeometryCollection();
+ gc.add(new Point(100, 0));
+ gc.add(new LineString(new LngLatAlt(101, 0), new LngLatAlt(102, 1)));
+ assertEquals("{\"type\":\"GeometryCollection\","
+ + "\"geometries\":[{\"type\":\"Point\",\"coordinates\":[100.0,0.0]},"
+ + "{\"type\":\"LineString\",\"coordinates\":[[101.0,0.0],[102.0,1.0]]}]}",
+ mapper.writeValueAsString(gc));
+ }
+
+ @Test
+ public void itShouldDeserialize() throws Exception {
+ GeometryCollection geometryCollection = mapper
+ .readValue("{\"type\":\"GeometryCollection\","
+ + "\"geometries\":[{\"type\":\"Point\",\"coordinates\":[100.0,0.0]},"
+ + "{\"type\":\"LineString\",\"coordinates\":[[101.0,0.0],[102.0,1.0]]}]}",
+ GeometryCollection.class);
+ assertNotNull(geometryCollection);
+ }
+
+ @Test
+ public void itShouldDeserializeSubtype() throws Exception {
+ FeatureCollection collection = mapper
+ .readValue("{\"type\": \"FeatureCollection\","
+ + " \"features\": ["
+ + " {"
+ + " \"type\": \"Feature\","
+ + " \"geometry\": {"
+ + " \"type\": \"GeometryCollection\","
+ + " \"geometries\": ["
+ + " {"
+ + " \"type\": \"Point\","
+ + " \"coordinates\": [100.0, 0.0]"
+ + " }"
+ + " ]"
+ + " }"
+ + " }"
+ + " ]"
+ + "}",
+ FeatureCollection.class);
+ assertNotNull(collection);
+ assertTrue(collection.getFeatures().get(0).getGeometry() instanceof GeometryCollection);
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/LineStringTest.java b/src/test/java/org/geojson/jackson/LineStringTest.java
new file mode 100644
index 0000000..49aa101
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/LineStringTest.java
@@ -0,0 +1,34 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LineString;
+import org.geojson.LngLatAlt;
+import org.geojson.MultiPoint;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class LineStringTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerializeMultiPoint() throws Exception {
+ MultiPoint lineString = new LineString(new LngLatAlt(100, 0), new LngLatAlt(101, 1));
+ assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}",
+ mapper.writeValueAsString(lineString));
+ }
+
+ @Test
+ public void itShouldDeserializeLineString() throws Exception {
+ LineString lineString = mapper.readValue("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}",
+ LineString.class);
+ assertNotNull(lineString);
+ List<LngLatAlt> coordinates = lineString.getCoordinates();
+ PointTest.assertLngLatAlt(100, 0, Double.NaN, coordinates.get(0));
+ PointTest.assertLngLatAlt(101, 1, Double.NaN, coordinates.get(1));
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/LngLatAltDeserializerTest.java b/src/test/java/org/geojson/jackson/LngLatAltDeserializerTest.java
new file mode 100644
index 0000000..5d204b8
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/LngLatAltDeserializerTest.java
@@ -0,0 +1,21 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LngLatAlt;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Created by babbleshack on 27/11/16.
+ */
+public class LngLatAltDeserializerTest {
+ @Test
+ public void deserializeMongoLngLatAlt() throws Exception {
+ LngLatAlt lngLatAlt = new LngLatAlt(10D, 15D, 5);
+ String lngLatAltJson = new ObjectMapper().writeValueAsString(lngLatAlt);
+ lngLatAltJson.replace("10.0", "\"10.0\"");
+ lngLatAltJson.replace("15.0", "\"15.0\"");
+ LngLatAlt lngLatAlt1 = new ObjectMapper().readValue(lngLatAltJson, LngLatAlt.class);
+ Assert.assertTrue(lngLatAlt.equals(lngLatAlt));
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/LngLatAltSerializerTest.java b/src/test/java/org/geojson/jackson/LngLatAltSerializerTest.java
new file mode 100644
index 0000000..ee20e08
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/LngLatAltSerializerTest.java
@@ -0,0 +1,20 @@
+package org.geojson.jackson;
+
+import org.geojson.LngLatAlt;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class LngLatAltSerializerTest
+{
+
+ @Test
+ public void testSerialization() throws Exception
+ {
+ LngLatAlt position = new LngLatAlt(49.43245, 52.42345, 120.34626);
+ String correctJson = "[49.43245,52.42345,120.34626]";
+ String producedJson = new ObjectMapper().writeValueAsString(position);
+ Assert.assertEquals(correctJson, producedJson);
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/MockData.java b/src/test/java/org/geojson/jackson/MockData.java
new file mode 100644
index 0000000..cbcfcc8
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/MockData.java
@@ -0,0 +1,14 @@
+package org.geojson.jackson;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.geojson.LngLatAlt;
+
+public class MockData {
+
+ public static final List<LngLatAlt> EXTERNAL = Arrays.asList(new LngLatAlt(100, 0), new LngLatAlt(101, 0),
+ new LngLatAlt(101, 1), new LngLatAlt(100, 1), new LngLatAlt(100, 0));
+ public static final List<LngLatAlt> INTERNAL = Arrays.asList(new LngLatAlt(100.2, 0.2), new LngLatAlt(100.8, 0.2),
+ new LngLatAlt(100.8, 0.8), new LngLatAlt(100.2, 0.8), new LngLatAlt(100.2, 0.2));
+}
diff --git a/src/test/java/org/geojson/jackson/MultiLineStringTest.java b/src/test/java/org/geojson/jackson/MultiLineStringTest.java
new file mode 100644
index 0000000..a877b0b
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/MultiLineStringTest.java
@@ -0,0 +1,24 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LngLatAlt;
+import org.geojson.MultiLineString;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+
+public class MultiLineStringTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerialize() throws Exception {
+ MultiLineString multiLineString = new MultiLineString();
+ multiLineString.add(Arrays.asList(new LngLatAlt(100, 0), new LngLatAlt(101, 1)));
+ multiLineString.add(Arrays.asList(new LngLatAlt(102, 2), new LngLatAlt(103, 3)));
+ assertEquals("{\"type\":\"MultiLineString\",\"coordinates\":"
+ + "[[[100.0,0.0],[101.0,1.0]],[[102.0,2.0],[103.0,3.0]]]}", mapper.writeValueAsString(multiLineString));
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/MultiPointTest.java b/src/test/java/org/geojson/jackson/MultiPointTest.java
new file mode 100644
index 0000000..4217468
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/MultiPointTest.java
@@ -0,0 +1,34 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LngLatAlt;
+import org.geojson.MultiPoint;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MultiPointTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerializeMultiPoint() throws Exception {
+ MultiPoint multiPoint = new MultiPoint(new LngLatAlt(100, 0), new LngLatAlt(101, 1));
+ assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}",
+ mapper.writeValueAsString(multiPoint));
+ }
+
+ @Test
+ public void itShouldDeserializeMultiPoint() throws Exception {
+ MultiPoint multiPoint = mapper
+ .readValue("{\"type\":\"MultiPoint\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}",
+ MultiPoint.class);
+ assertNotNull(multiPoint);
+ List<LngLatAlt> coordinates = multiPoint.getCoordinates();
+ PointTest.assertLngLatAlt(100, 0, Double.NaN, coordinates.get(0));
+ PointTest.assertLngLatAlt(101, 1, Double.NaN, coordinates.get(1));
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/MultiPoligonTest.java b/src/test/java/org/geojson/jackson/MultiPoligonTest.java
new file mode 100644
index 0000000..fe60d4e
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/MultiPoligonTest.java
@@ -0,0 +1,38 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LngLatAlt;
+import org.geojson.MultiPolygon;
+import org.geojson.Polygon;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class MultiPoligonTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerialize() throws Exception {
+ MultiPolygon multiPolygon = new MultiPolygon();
+ multiPolygon.add(new Polygon(new LngLatAlt(102, 2), new LngLatAlt(103, 2), new LngLatAlt(103, 3),
+ new LngLatAlt(102, 3), new LngLatAlt(102, 2)));
+ Polygon polygon = new Polygon(MockData.EXTERNAL);
+ polygon.addInteriorRing(MockData.INTERNAL);
+ multiPolygon.add(polygon);
+ assertEquals(
+ "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]]],"
+ + "[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],"
+ + "[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]]}",
+ mapper.writeValueAsString(multiPolygon));
+ }
+
+ @Test
+ public void itShouldDeserialize() throws Exception {
+ MultiPolygon multiPolygon = mapper.readValue(
+ "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]]],"
+ + "[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],"
+ + "[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]]}", MultiPolygon.class);
+ assertEquals(2, multiPolygon.getCoordinates().size());
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/PointTest.java b/src/test/java/org/geojson/jackson/PointTest.java
new file mode 100644
index 0000000..0711557
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/PointTest.java
@@ -0,0 +1,89 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.GeoJsonObject;
+import org.geojson.LngLatAlt;
+import org.geojson.Point;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class PointTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ public static void assertLngLatAlt(double expectedLongitude, double expectedLatitude, double expectedAltitude,
+ LngLatAlt point) {
+ assertLngLatAlt(expectedLongitude, expectedLatitude, expectedAltitude, new double[0], point);
+ }
+
+ public static void assertLngLatAlt(double expectedLongitude, double expectedLatitude, double expectedAltitude,
+ double[] expectedAdditionalElements, LngLatAlt point) {
+ assertEquals(expectedLongitude, point.getLongitude(), 0.00001);
+ assertEquals(expectedLatitude, point.getLatitude(), 0.00001);
+ if (Double.isNaN(expectedAltitude)) {
+ assertFalse(point.hasAltitude());
+ } else {
+ assertEquals(expectedAltitude, point.getAltitude(), 0.00001);
+ assertTrue(Arrays.equals(expectedAdditionalElements, point.getAdditionalElements()));
+ }
+ }
+
+ @Test
+ public void itShouldSerializeAPoint() throws Exception {
+ Point point = new Point(100, 0);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[100.0,0.0]}",
+ mapper.writeValueAsString(point));
+ }
+
+ @Test
+ public void itShouldDeserializeAPoint() throws Exception {
+ GeoJsonObject value = mapper
+ .readValue("{\"type\":\"Point\",\"coordinates\":[100.0,5.0]}", GeoJsonObject.class);
+ assertNotNull(value);
+ assertTrue(value instanceof Point);
+ Point point = (Point)value;
+ assertLngLatAlt(100, 5, Double.NaN, point.getCoordinates());
+ }
+
+ @Test
+ public void itShouldDeserializeAPointWithAltitude() throws Exception {
+ GeoJsonObject value = mapper.readValue("{\"type\":\"Point\",\"coordinates\":[100.0,5.0,123]}",
+ GeoJsonObject.class);
+ Point point = (Point)value;
+ assertLngLatAlt(100, 5, 123, point.getCoordinates());
+ }
+
+ @Test
+ public void itShouldSerializeAPointWithAltitude() throws Exception {
+ Point point = new Point(100, 0, 256);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[100.0,0.0,256.0]}",
+ mapper.writeValueAsString(point));
+ }
+
+ @Test
+ public void itShouldDeserializeAPointWithAdditionalAttributes() throws IOException {
+ GeoJsonObject value = mapper.readValue("{\"type\":\"Point\",\"coordinates\":[100.0,5.0,123,456,789.2]}",
+ GeoJsonObject.class);
+ Point point = (Point)value;
+ assertLngLatAlt(100, 5, 123, new double[] {456d, 789.2}, point.getCoordinates());
+ }
+
+ @Test
+ public void itShouldSerializeAPointWithAdditionalAttributes() throws JsonProcessingException {
+ Point point = new Point(100, 0, 256, 345d, 678d);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[100.0,0.0,256.0,345.0,678.0]}",
+ mapper.writeValueAsString(point));
+ }
+
+ @Test
+ public void itShouldSerializeAPointWithAdditionalAttributesAndNull() throws JsonProcessingException {
+ Point point = new Point(100, 0, 256, 345d, 678d);
+ assertEquals("{\"type\":\"Point\",\"coordinates\":[100.0,0.0,256.0,345.0,678.0]}",
+ mapper.writeValueAsString(point));
+ }
+}
diff --git a/src/test/java/org/geojson/jackson/PolygonTest.java b/src/test/java/org/geojson/jackson/PolygonTest.java
new file mode 100644
index 0000000..6298483
--- /dev/null
+++ b/src/test/java/org/geojson/jackson/PolygonTest.java
@@ -0,0 +1,74 @@
+package org.geojson.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.geojson.LngLatAlt;
+import org.geojson.Polygon;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class PolygonTest {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Test
+ public void itShouldSerialize() throws Exception {
+ Polygon polygon = new Polygon(MockData.EXTERNAL);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":"
+ + "[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}",
+ mapper.writeValueAsString(polygon));
+ }
+
+ @Test
+ public void itShouldSerializeWithHole() throws Exception {
+ Polygon polygon = new Polygon(MockData.EXTERNAL);
+ polygon.addInteriorRing(MockData.INTERNAL);
+ assertEquals("{\"type\":\"Polygon\",\"coordinates\":"
+ + "[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],"
+ + "[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", mapper.writeValueAsString(polygon));
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void itShouldFailOnAddInteriorRingWithoutExteriorRing() throws Exception {
+ Polygon polygon = new Polygon();
+ polygon.addInteriorRing(MockData.EXTERNAL);
+ }
+
+ @Test
+ public void itShouldDeserialize() throws Exception {
+ Polygon polygon = mapper.readValue("{\"type\":\"Polygon\",\"coordinates\":"
+ + "[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],"
+ + "[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}", Polygon.class);
+ assertListEquals(MockData.EXTERNAL, polygon.getExteriorRing());
+ assertListEquals(MockData.INTERNAL, polygon.getInteriorRing(0));
+ assertListEquals(MockData.INTERNAL, polygon.getInteriorRings().get(0));
+ }
+
+ @Test
+ public void itShouldSetExteriorRing() throws Exception {
+ Polygon polygon = new Polygon();
+ polygon.setExteriorRing(MockData.EXTERNAL);
+ assertEquals(MockData.EXTERNAL, polygon.getExteriorRing());
+ }
+
+ @Test
+ public void itShouldReplaceExteriorRing() throws Exception {
+ Polygon polygon = new Polygon(Arrays.asList(
+ new LngLatAlt(0, 0), new LngLatAlt(1, 0), new LngLatAlt(1, 1), new LngLatAlt(0, 1), new LngLatAlt(0, 0)));
+ polygon.setExteriorRing(MockData.EXTERNAL);
+ assertEquals(MockData.EXTERNAL, polygon.getExteriorRing());
+ assertEquals(0, polygon.getInteriorRings().size());
+ }
+
+ private void assertListEquals(List<LngLatAlt> expectedList, List<LngLatAlt> actualList) {
+ for (int x = 0; x < actualList.size(); x++) {
+ LngLatAlt expected = expectedList.get(x);
+ LngLatAlt actual = actualList.get(x);
+ PointTest.assertLngLatAlt(expected.getLongitude(), expected.getLatitude(), expected.getAltitude(), actual);
+ }
+ }
+}