View Javadoc
1   /*
2    * Copyright 2022 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.geojson.converter.serialization;
18  
19  import static java.util.Collections.unmodifiableList;
20  import static java.util.Collections.unmodifiableMap;
21  import static java.util.Objects.isNull;
22  
23  import java.io.Serial;
24  import java.io.Serializable;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Optional;
31  import java.util.stream.Collectors;
32  import org.bremersee.geojson.GeoJsonConstants;
33  import org.bremersee.geojson.GeoJsonGeometryFactory;
34  import org.locationtech.jts.geom.Geometry;
35  import org.locationtech.jts.geom.GeometryCollection;
36  import org.locationtech.jts.geom.LineString;
37  import org.locationtech.jts.geom.MultiLineString;
38  import org.locationtech.jts.geom.MultiPoint;
39  import org.locationtech.jts.geom.MultiPolygon;
40  import org.locationtech.jts.geom.Point;
41  import org.locationtech.jts.geom.Polygon;
42  
43  /**
44   * The geometry to json converter.
45   *
46   * @author Christian Bremer
47   */
48  public class GeometryToJsonConverter implements Serializable {
49  
50    @Serial
51    private static final long serialVersionUID = 1L;
52  
53    /**
54     * The point converter.
55     */
56    private final PointToJsonConverter pointConverter;
57  
58    /**
59     * The Line string converter.
60     */
61    private final LineStringToJsonConverter lineStringConverter;
62  
63    /**
64     * The Polygon converter.
65     */
66    private final PolygonToJsonConverter polygonConverter;
67  
68    /**
69     * The Multi point converter.
70     */
71    private final MultiPointToJsonConverter multiPointConverter;
72  
73    /**
74     * The Multi line string converter.
75     */
76    private final MultiLineStringToJsonConverter multiLineStringConverter;
77  
78    /**
79     * The Multi polygon converter.
80     */
81    private final MultiPolygonToJsonConverter multiPolygonConverter;
82  
83    /**
84     * Specifies whether a bounding box should be generated or not.
85     */
86    private final boolean withBoundingBox;
87  
88    /**
89     * Instantiates a new geometry to json converter.
90     */
91    public GeometryToJsonConverter() {
92      this(false, false);
93    }
94  
95    /**
96     * Instantiates a new geometry to json converter.
97     *
98     * @param withBoundingBox with bounding box
99     * @param useBigDecimal use big decimal
100    */
101   public GeometryToJsonConverter(boolean withBoundingBox, boolean useBigDecimal) {
102     CoordinateToListConverter coordinateConverter = new CoordinateToListConverter(useBigDecimal);
103     CoordinateSequenceToListConverter coordinateSequenceConverter
104         = new CoordinateSequenceToListConverter(coordinateConverter);
105 
106     pointConverter = new PointToJsonConverter(coordinateConverter, withBoundingBox);
107     lineStringConverter = new LineStringToJsonConverter(
108         coordinateSequenceConverter,
109         withBoundingBox);
110     polygonConverter = new PolygonToJsonConverter(coordinateSequenceConverter, withBoundingBox);
111 
112     multiPointConverter = new MultiPointToJsonConverter(pointConverter, withBoundingBox);
113     multiLineStringConverter = new MultiLineStringToJsonConverter(
114         lineStringConverter,
115         withBoundingBox);
116     multiPolygonConverter = new MultiPolygonToJsonConverter(polygonConverter, withBoundingBox);
117 
118     this.withBoundingBox = withBoundingBox;
119   }
120 
121   /**
122    * Convert map.
123    *
124    * @param source the source
125    * @return the map
126    */
127   public Map<String, Object> convert(Geometry source) {
128     if (isNull(source)) {
129       return null;
130     }
131     if (source instanceof Point) {
132       return pointConverter.convert((Point) source);
133     }
134 
135     if (source instanceof LineString) {
136       return lineStringConverter.convert((LineString) source);
137     }
138 
139     if (source instanceof Polygon) {
140       return polygonConverter.convert((Polygon) source);
141     }
142 
143     if (source instanceof MultiPoint) {
144       return multiPointConverter.convert((MultiPoint) source);
145     }
146 
147     if (source instanceof MultiLineString) {
148       return multiLineStringConverter.convert((MultiLineString) source);
149     }
150 
151     if (source instanceof MultiPolygon) {
152       return multiPolygonConverter.convert((MultiPolygon) source);
153     }
154 
155     if (source instanceof GeometryCollection) {
156       List<Map<String, Object>> geometries = new ArrayList<>(source.getNumGeometries());
157       for (int i = 0; i < source.getNumGeometries(); i++) {
158         geometries.add(convert(source.getGeometryN(i)));
159       }
160       Map<String, Object> map = new LinkedHashMap<>();
161       map.put(GeoJsonConstants.TYPE, GeoJsonConstants.GEOMETRY_COLLECTION);
162       if (withBoundingBox) {
163         Optional.ofNullable(GeoJsonGeometryFactory.getBoundingBox(source))
164             .map(bbox -> Arrays.stream(bbox).boxed().collect(Collectors.toList()))
165             .ifPresent(bbox -> map.put(GeoJsonConstants.BBOX, bbox));
166       }
167       map.put(GeoJsonConstants.GEOMETRIES, unmodifiableList(geometries));
168       return unmodifiableMap(map);
169     }
170 
171     throw new IllegalArgumentException("Geometry [" + source + "] is unsupported. It must be "
172         + "an instance of Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon "
173         + "or GeometryCollection.");
174   }
175 }