root/tools/routingservice/branches/wrs-2.0/lib/org/mapfish/geo/MfGeoJSONWriter.java

Revision 337, 8.9 KB (checked in by anton, 14 months ago)

Multiple improvements:

  • aggregate functions
  • capabilities service
Line 
1/*
2 * Copyright (C) 2009  Camptocamp
3 *
4 * This file is part of MapFish Server
5 *
6 * MapFish Server is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * MapFish Server is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with MapFish Server.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
22 * This code is licensed under the GPL 2.0 license, availible at the root
23 * application directory.
24 */
25
26/*
27 * MfGeoJSON.java
28 */
29
30package org.mapfish.geo;
31
32import com.vividsolutions.jts.geom.Coordinate;
33import com.vividsolutions.jts.geom.Envelope;
34import com.vividsolutions.jts.geom.Geometry;
35import com.vividsolutions.jts.geom.GeometryCollection;
36import com.vividsolutions.jts.geom.LineString;
37import com.vividsolutions.jts.geom.MultiLineString;
38import com.vividsolutions.jts.geom.MultiPoint;
39import com.vividsolutions.jts.geom.MultiPolygon;
40import com.vividsolutions.jts.geom.Point;
41import com.vividsolutions.jts.geom.Polygon;
42import org.json.JSONException;
43import org.json.JSONWriter;
44
45import java.util.Iterator;
46
47
48/**
49 * This class is coded against the version 1.0 of the spec
50 * on http://geojson.org.
51 *
52 * The code of this class is greatly inspired from the GeoJSONBuilder
53 * class from the GeoServer code base. The author of that class is
54 * Chris Holmes, from the Open Planning Project. See the above
55 * copyright.
56 *
57 * @author Eric Lemoine, Camptocamp.
58 * @version $Id$
59 *
60 */
61public class MfGeoJSONWriter {
62    private final JSONWriter builder;
63
64    public MfGeoJSONWriter(JSONWriter builder) {
65        this.builder = builder;
66    }
67
68    public void encode(MfGeo o) throws JSONException {
69        switch (o.getGeoType()) {
70            case FEATURE:
71                MfFeature f = (MfFeature)o;
72                encodeFeature(f);
73                break;
74            case FEATURECOLLECTION:
75                MfFeatureCollection c = (MfFeatureCollection)o;
76                encodeFeatureCollection(c);
77                break;
78            case GEOMETRY:
79                MfGeometry g = (MfGeometry)o;
80                encodeGeometry(g.getInternalGeometry());
81                break;
82             default:
83                throw new RuntimeException("No implementation for " + o.getGeoType());
84        }
85    }
86
87    public void encodeFeatureCollection(MfFeatureCollection c) throws JSONException {
88        builder.object();
89        builder.key("type").value("FeatureCollection");
90        builder.key("features");
91        builder.array();
92
93        Iterator<MfFeature> i = c.getCollection().iterator();
94        while (i.hasNext()) {
95            MfFeature f = i.next();
96            encodeFeature(f);
97        }
98
99        builder.endArray();
100        builder.endObject();
101    }
102
103    public void encodeFeature(MfFeature f) throws JSONException {
104        builder.object();
105        builder.key("type").value("Feature");
106        builder.key("id").value(f.getFeatureId());
107        builder.key("geometry");
108
109        Geometry g;
110        MfGeometry mfg;
111        if (((mfg = f.getMfGeometry()) != null) &&
112            ((g = mfg.getInternalGeometry()) != null)) {
113            encodeGeometry(g);
114        } else {
115            builder.value(null);
116        }
117
118        builder.key("properties");
119        builder.object();
120        f.toJSON(builder);
121        builder.endObject();
122        builder.endObject();
123    }
124
125    public void encodeGeometry(Geometry g) throws JSONException {
126
127        builder.object();
128        builder.key("type");
129        builder.value(getGeometryName(g));
130
131        GeometryType geometryType = getGeometryType(g);
132
133        if (geometryType != GeometryType.MULTIGEOMETRY) {
134            builder.key("coordinates");
135
136            switch (geometryType) {
137            case POINT:
138                encodeCoordinate(g.getCoordinate());
139                break;
140
141            case LINESTRING:
142            case MULTIPOINT:
143                encodeCoordinates(g.getCoordinates());
144                break;
145
146            case POLYGON:
147                encodePolygon((Polygon) g);
148                break;
149
150            case MULTILINESTRING:
151                builder.array();
152                for (int i = 0, n = g.getNumGeometries(); i < n; i++) {
153                    encodeCoordinates(g.getGeometryN(i).getCoordinates());
154                }
155                builder.endArray();
156                break;
157
158            case MULTIPOLYGON:
159                builder.array();
160                for (int i = 0, n = g.getNumGeometries(); i < n; i++) {
161                    encodePolygon((Polygon) g.getGeometryN(i));
162                }
163                builder.endArray();
164                break;
165
166            default:
167                //should never happen.
168                throw new RuntimeException("No implementation for "+geometryType);
169            }
170        } else {
171            encodeGeomCollection((GeometryCollection) g);
172        }
173
174        builder.endObject();
175    }
176
177    private void encodeGeomCollection(GeometryCollection collection) throws JSONException {
178        builder.array();
179        builder.key("geometries");
180
181        for (int i = 0, n = collection.getNumGeometries(); i < n; i++) {
182            encodeGeometry(collection.getGeometryN(i));
183        }
184
185        builder.endArray();
186    }
187
188    /**
189     * Write the coordinates of a geometry
190     * @param coords The coordinates to encode
191     * @throws JSONException
192     */
193    private void encodeCoordinates(Coordinate[] coords)
194        throws JSONException {
195        builder.array();
196
197        for (int i = 0; i < coords.length; i++) {
198            Coordinate coord = coords[i];
199            encodeCoordinate(coord);
200        }
201
202        builder.endArray();
203    }
204
205    private void encodeCoordinate(Coordinate coord) throws JSONException {
206        builder.array();
207        builder.value(coord.x);
208        builder.value(coord.y);
209        builder.endArray();
210    }
211
212    /**
213     * Turns an envelope into an array [minX,minY,maxX,maxY]
214     * @param env envelope representing bounding box
215     */
216    protected void encodeBoundingBox(Envelope env) throws JSONException {
217        builder.key("bbox");
218        builder.array();
219        builder.value(env.getMinX());
220        builder.value(env.getMinY());
221        builder.value(env.getMaxX());
222        builder.value(env.getMaxY());
223        builder.endArray();
224    }
225
226    /**
227     * Writes a polygon
228     * @param geometry The polygon to encode
229     * @throws JSONException
230     */
231    private void encodePolygon(Polygon geometry) throws JSONException {
232        builder.array();
233        encodeCoordinates(geometry.getExteriorRing().getCoordinates());
234
235        for (int i = 0, ii = geometry.getNumInteriorRing(); i < ii; i++) {
236            encodeCoordinates(geometry.getInteriorRingN(i).getCoordinates());
237        }
238
239        builder.endArray(); //end the linear ring
240    }
241
242    public static enum GeometryType {
243        POINT("Point"),
244        LINESTRING("LineString"),
245        POLYGON("Polygon"),
246        MULTIPOINT("MultiPoint"),
247        MULTILINESTRING("MultiLineString"),
248        MULTIPOLYGON("MultiPolygon"),
249        MULTIGEOMETRY("GeometryCollection");
250
251        private final String name;
252
253        private GeometryType(String name) {
254            this.name = name;
255        }
256
257        public String getName() {
258            return name;
259        }
260    }
261
262    public static String getGeometryName(Geometry geometry) {
263        final GeometryType type = getGeometryType(geometry);
264        return type != null ? type.getName() : null;
265    }
266
267    /**
268     * Gets the internal representation for the given Geometry
269     *
270     * @param geometry a Geometry
271     *
272     * @return int representation of Geometry
273     */
274    public static GeometryType getGeometryType(Geometry geometry) {
275        final Class<?> geomClass = geometry.getClass();
276        final GeometryType returnValue;
277
278        if (geomClass.equals(Point.class)) {
279            returnValue = GeometryType.POINT;
280        } else if (geomClass.equals(LineString.class)) {
281            returnValue = GeometryType.LINESTRING;
282        } else if (geomClass.equals(Polygon.class)) {
283            returnValue = GeometryType.POLYGON;
284        } else if (geomClass.equals(MultiPoint.class)) {
285            returnValue = GeometryType.MULTIPOINT;
286        } else if (geomClass.equals(MultiLineString.class)) {
287            returnValue = GeometryType.MULTILINESTRING;
288        } else if (geomClass.equals(MultiPolygon.class)) {
289            returnValue = GeometryType.MULTIPOLYGON;
290        } else if (geomClass.equals(GeometryCollection.class)) {
291            returnValue = GeometryType.MULTIGEOMETRY;
292        } else {
293            returnValue = null;
294            //HACK!!! throw exception.
295        }
296
297        return returnValue;
298    }
299}
Note: See TracBrowser for help on using the browser.