diff options
author | Neil Fuller <nfuller@google.com> | 2020-08-05 20:53:53 +0100 |
---|---|---|
committer | Neil Fuller <nfuller@google.com> | 2020-08-05 20:53:53 +0100 |
commit | 2431afb27465e3663dbb545f1f46344367809649 (patch) | |
tree | 65054c253fdd75105b9ea0f26d5d55ca665f5c8a | |
parent | cfd5e8ffb76c3bc3cf83a69eee64deadb5672f2d (diff) | |
parent | b02f8a3a10c09fe673aaf3530ec640cb8e80bebb (diff) | |
download | geojson-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
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 @@ -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> +``` + @@ -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); + } + } +} |