root/tools/routingservice/trunk/src/jp/co/orkney/restlet/util/IOHelper.java

Revision 276, 18.7 KB (checked in by anton, 21 months ago)

Big cleaning at IOHelper class

Line 
1package jp.co.orkney.restlet.util;
2
3/**
4 * Copyright (c) 2008 Orkney, Inc. <http://www.orkney.co.jp/>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU 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 * This program 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 General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20import java.io.BufferedInputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.IOException;
24import java.io.StringWriter;
25import java.math.BigDecimal;
26import java.sql.ResultSet;
27import java.sql.SQLException;
28import java.util.ArrayList;
29
30import org.antlr.stringtemplate.StringTemplate;
31import org.antlr.stringtemplate.StringTemplateGroup;
32import org.json.JSONArray;
33import org.json.JSONException;
34import org.json.JSONObject;
35import org.restlet.ext.json.JsonRepresentation;
36
37/**
38 * <b>IOHelper is a class which provides some tools for Closest Edge and
39 * Shortest Path algorithms.</b>
40 * <p>
41 * IOHelper class is like the WebRouting Service's "tool box". An IOHelper
42 * object provides methods for:
43 * <ul>
44 * <li>Extract X and Y from each data source format</li>
45 * <li>Make the result of Closest Edge or Shortest Path algorithm in each
46 * available format</li>
47 * </ul>
48 * </p>
49 *
50 * @author Matthieu Bilbille - Orkney Inc.
51 * @version 1.0
52 */
53public class IOHelper
54{
55
56        private Log log;
57        private Configuration configuration;
58
59        /**
60         * Constructor IOHelper
61         * <p>
62         * Creates a new IOHelper object using the specified Configuration object
63         * </p>
64         *
65         * @param configuration
66         *            the current configuration
67         */
68        public IOHelper(Configuration configuration)
69        {
70                this.configuration = configuration;
71                this.log = configuration.createLog();
72        }
73
74        /**
75         * <p>
76         * Extracts X and Y from Geojson data and creates a new point with these
77         * coordinates
78         * </p>
79         *
80         * @param data
81         *            data provided by GET or POST Request
82         * @return a point with X and Y values extracted from the specified string
83         * @see Point
84         */
85        public Point extractGEOJSONPxPy(String data)
86        {
87                Point point = new Point();
88
89                try
90                {
91                        JSONObject json = new JsonRepresentation(data).toJsonObject();
92                        point.setX(new BigDecimal(json.getJSONObject("geometry").getJSONArray("coordinates").getString(0)));
93                        point.setY(new BigDecimal(json.getJSONObject("geometry").getJSONArray("coordinates").getString(1)));
94                }
95                catch (JSONException e)
96                {
97                        log.write("--ERROR: Can not extract X and Y from Json object", 0);
98                }
99
100                return point;
101        }
102
103        /**
104         * <p>
105         * Extracts X and Y from Gml data and creates a new point with these
106         * coordinates
107         * </p>
108         *
109         * @param data
110         *            data provided by GET or POST Request
111         * @return a point with X and Y values extracted from the specified string
112         * @see Point
113         */
114        public Point extractGMLPxPy(String data)
115        {
116                Point point = new Point();
117                data = data.split("<gml:coordinates.*?>")[1].split("<\\/gml:coordinates>")[0];
118                point.setX(new BigDecimal(data.split(",")[0]));
119                point.setY(new BigDecimal(data.split(",")[1]));
120                return point;
121        }
122
123        /**
124         * <p>
125         * Extracts X and Y from "LonLat" data and creates a new point with these
126         * coordinates
127         * </p>
128         *
129         * @param data
130         *            data provided by GET or POST Request
131         * @return a point with X and Y values extracted from the specified string
132         * @see Point
133         */
134        public Point extractLONLATPxPy(String data)
135        {
136                Point point = new Point();
137                point.setX(new BigDecimal(data.split(" ")[0]));
138                point.setY(new BigDecimal(data.split(" ")[1]));
139                return point;
140        }
141
142        /**
143         * <p>
144         * Extracts X and Y from WKT data and creates a new point with these
145         * coordinates
146         * </p>
147         *
148         * @param data
149         *            data provided by GET or POST Request
150         * @return a point with X and Y values extracted from the specified string
151         * @see Point
152         */
153        public Point extractWKTPxPy(String data)
154        {
155                Point point = new Point();
156                data = data.split("POINT\\(")[1].split("\\)")[0];
157                point.setX(new BigDecimal(data.split(" ")[0]));
158                point.setY(new BigDecimal(data.split(" ")[1]));
159                return point;
160        }
161
162        /**
163         * <p>
164         * Extracts X and Y from Kml data and creates a new point with these
165         * coordinates
166         * </p>
167         *
168         * @param data
169         *            data provided by GET or POST Request
170         * @return a point with X and Y values extracted from the specified string
171         * @see Point
172         */
173        public Point extractKMLPxPy(String data)
174        {
175                Point point = new Point();
176                data = data.split("<coordinates>")[1].split("<\\/coordinates>")[0];
177                point.setX(new BigDecimal(data.split(",")[0]));
178                point.setY(new BigDecimal(data.split(",")[1]));
179                return point;
180        }
181
182        /**
183         * <p>
184         * Extracts points from data and puts them within an array of string
185         * </p>
186         *
187         * @param data
188         *            data provided by GET or POST Request
189         * @return an array of string points
190         */
191        public String[] extractPoints(String data, String regex)
192        {
193                return data.split(regex);
194        }
195
196        /**
197         * Draws the result of the driving distance algorithm in Geojson format
198         *
199         * @param resultSet
200         *            result of the SQL query
201         * @return result this query's result in Geojson format
202         * @throws SQLException
203         *             Error to extract data from ResultSet object *
204         * @throws JSONException
205         *             Error to make Geojson object
206         */
207        public String drivingDistanceGEOJSONResult(ResultSet resultSet, String reqId) throws SQLException, JSONException
208        {
209                String result = "";
210                JSONObject joRes = new JSONObject();
211                JSONObject joGeo = new JSONObject();
212                JSONObject joPro = new JSONObject();
213                JSONObject joCrs = new JSONObject();
214
215                JSONObject joPro2 = new JSONObject();
216                JSONArray joCor = new JSONArray();
217
218                if (resultSet != null && resultSet.next())
219                {
220                        joRes.put("type", "Feature");
221
222                        joPro.put("pid", "id_polygon");
223                        joPro.put("name", "name_polygon");
224                        joRes.put("properties", joPro);
225
226                        joGeo.put("type", "Polygon");
227                        String tmpSplit = resultSet.getString("wkt");
228                        tmpSplit = tmpSplit.split("POLYGON\\(\\(")[1].split("\\)\\)")[0];
229                        String wkt[] = tmpSplit.split(",");
230                        JSONArray tmp = new JSONArray();
231                        for (int i = 0; i < wkt.length; i++)
232                        {
233                                JSONArray tmp2 = new JSONArray();
234                                tmp2.put(new BigDecimal(wkt[i].split(" ")[0]));
235                                tmp2.put(new BigDecimal(wkt[i].split(" ")[1]));
236                                tmp.put(tmp2);
237                        }
238                        joCor.put(tmp);
239
240                        joGeo.put("coordinates", joCor);
241                        joRes.put("geometry", joGeo);
242
243                        joCrs.put("type", "EPSG");
244                        joPro2.put("code", "900913");
245                        joCrs.put("properties", joPro2);
246                        joRes.put("crs", joCrs);
247                }
248                else
249                {
250                        joRes.put("type", "Feature");
251
252                        joPro.put("pid", 0);
253                        joPro.put("name", "unknow_polygon");
254                        joRes.put("properties", joPro);
255
256                        joGeo.put("type", "Polygon");
257                        JSONArray tmp = new JSONArray();
258                        joCor.put(tmp);
259                        joGeo.put("coordinates", joCor);
260                        joRes.put("geometry", joGeo);
261
262                        joCrs.put("type", "EPSG");
263                        joPro2.put("code", configuration.getService().getDataProjection());
264                        joCrs.put("properties", joPro2);
265                        joRes.put("crs", joCrs);
266                }
267               
268                joRes.put("requestId", reqId);
269               
270                result = joRes.toString();
271                return result;
272        }
273
274        /**
275         * Draws the result of the driving distance algorithm in WKT format
276         *
277         * @param resultSet
278         *            result of the SQL query
279         * @return result this query's result in WKT format
280         * @throws SQLException
281         *             Error to extract data from ResultSet object
282         */
283        public String drivingDistanceWKTResult(ResultSet resultSet) throws SQLException
284        {
285                String result = "";
286                if (resultSet != null && resultSet.next())
287                {
288                        result = resultSet.getString("wkt");
289                }
290                return result;
291        }
292
293        /**
294         * Draws the result of the driving distance algorithm in GML format
295         *
296         * @param resultSet
297         *            result of the SQL query
298         * @return result this query's result in GML format
299         * @throws SQLException
300         *             Error to extract data from ResultSet object
301         */
302        public String drivingDistanceGMLResult(ResultSet resultSet, String reqId) throws SQLException
303        {
304                String result = "<wfs:FeatureCollection xmlns:wfs=\"http://www.opengis.net/wfs\">"
305                                + "<gml:featureMember xmlns:gml=\"http://www.opengis.net/gml\">"
306                                + "<feature:features xmlns:feature=\"http://mapserver.gis.umn.edu/mapserver\">"
307                                + "<feature:geometry><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>";
308                if (resultSet != null && resultSet.next())
309                {
310                        String tmpSplit = resultSet.getString("wkt");
311                        tmpSplit = tmpSplit.split("POLYGON\\(\\(")[1].split("\\)\\)")[0];
312                        String wkt[] = tmpSplit.split(",");
313                        for (int i = 0; i < wkt.length; i++)
314                        {
315                                result += new BigDecimal(wkt[i].split(" ")[0]) + "," + new BigDecimal(wkt[i].split(" ")[1]) + " ";
316                        }
317                }
318                result += "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></feature:geometry></feature:features>"
319                                + "</gml:featureMember></wfs:FeatureCollection>";
320                return result;
321        }
322
323        /**
324         * Draws the result of the driving distance algorithm in KML format
325         *
326         * @param resultSet
327         *            result of the SQL query
328         * @return result this query's result in KML format
329         * @throws SQLException
330         *             Error to extract data from ResultSet object
331         */
332        public String drivingDistanceKMLResult(ResultSet resultSet) throws SQLException
333        {
334                String result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<kml xmlns=\"http://earth.google.com/kml/2.1\">"
335                                + "<Document><name>WebRouting Service</name><Style id=\"PolyStyle\"><PolyStyle><color>7f0000ff</color><width>4</width>"
336                                + "<fill>1</fill><outline>1</outline></PolyStyle></Style><Placemark>" + "<description>No+description+available</description>"
337                                + "<name>Isoline</name><styleUrl>#PolyStyle</styleUrl>"
338                                + "<Polygon><extrude>1</extrude><altitudeMode>clampToGround</altitudeMode><outerBoundaryIs>" + "<LinearRing><coordinates>";
339
340                if (resultSet != null && resultSet.next())
341                {
342                        String tmpSplit = resultSet.getString("wkt");
343                        tmpSplit = tmpSplit.split("POLYGON\\(\\(")[1].split("\\)\\)")[0];
344                        String wkt[] = tmpSplit.split(",");
345                        for (int i = 0; i < wkt.length; i++)
346                        {
347                                result += new BigDecimal(wkt[i].split(" ")[0]) + "," + new BigDecimal(wkt[i].split(" ")[1]) + ",30 ";
348                        }
349                }
350                result += " </coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark></Document></kml>";
351                return result;
352        }
353
354        /**
355         * Draws the result of the driving distance algorithm in XML format
356         *
357         * @param resultSet
358         *            result of the SQL query
359         * @return result this query's result in XML format
360         * @throws SQLException
361         *             Error to extract data from ResultSet object
362         */
363        public String drivingDistanceXMLResult(ResultSet resultSet, String reqId) throws SQLException
364        {
365                String result = "";
366                result = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n";
367                result += "<polygon>\n";
368                if (resultSet != null && resultSet.next())
369                {
370                        result += "\t<pid>id</pid>\n";
371                        result += "\t<name>name</name>\n";
372                        result += "\t<wkt>" + resultSet.getString("wkt") + "</wkt>\n";
373                }
374                else
375                {
376                        result += "\t<gid>0</gid>\n";
377                        result += "\t<name>unkown</name>\n";
378                }
379                result += "<requestid>"+reqId+"</requestid>\n";
380                result += "</polygon>\n";
381
382                return result;
383        }
384
385        /**
386         * Draws the result of the driving distance algorithm in HTML format
387         *
388         * @param resultSet
389         *            result of the SQL query
390         * @param point
391         *            point
392         * @return result this query's result in HTML format
393         * @throws SQLException
394         *             Error to extract data from ResultSet object
395         */
396        public String drivingDistanceHTMLResult(ResultSet resultSet, Point point, String reqId) throws SQLException
397        {
398                String result = "<html><head>" + "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + configuration.getCss() + "\" />"
399                                + "</head><body><table class=\"table\"><tr>";
400                result += "<td colspan=\"2\">From the point (" + point.getX() + ";" + point.getY() + "), isoline is: </td></tr>";
401                if (resultSet != null && resultSet.next())
402                {
403                        result += "<tr class=\"line\"><td>Geom:</td><td>" + resultSet.getString("wkt") + "</td></tr>";
404                }
405                else
406                {
407                        result += "<tr class=\"line\"><td>Geom:</td><td>-</td></tr>";
408                }
409                result += "<tr class=\"line\"><td>Request ID:</td><td>"+reqId+"</td></tr>";
410                result += "</body></html>";
411
412                return result;
413        }
414
415        /**
416         * <p>
417         * Returns the right SQL query to find either the closest edge or the
418         * shortest path. There are 4 kinds of query:
419         * <ul>
420         * <li>1. Input projection data, Output projection data and Database
421         * projection data are same. Default case</li>
422         * <li>2. Input projection data and Database projection data are same, but
423         * Output projection data is different (Example: KML is own projection
424         * format). It needs to transform output data in the right projection</li>
425         * <li>3. Database projection data and Output projection data are same, but
426         * Input projection data is different. It needs to transform input data in
427         * the right projection</li>
428         * <li>4. Input projection data, Output projection data and Database
429         * projection data are all different. It needs to transform input data in
430         * database projection data to make the SQL Query and after it, to transform
431         * again from database projection data to output projection</li>
432         * </ul>
433         * </p>
434         *
435         * @return a StringTemplate containing the right query for closestEdge or
436         *         shortestPath algorithms.
437         */
438        public StringTemplate getQuery()
439        {
440                StringTemplate query = null;
441                // sridInput and sridOuput are not specified
442                if ((configuration.getService().getParameter("sridInput").getValue() == null && configuration.getService().getParameter("sridOutput")
443                                .getValue() == null)
444                                || (configuration.getService().getDataProjection().equals(configuration.getService().getParameter("sridInput").getValue()) && configuration
445                                                .getService().getDataProjection().equals(configuration.getService().getParameter("sridOutput").getValue())))
446                {
447                        query = new StringTemplate(configuration.getService().getSQL(0));
448                }
449                // Only sridOutput is specified
450                else if ((configuration.getService().getParameter("sridInput").getValue() == null && configuration.getService().getParameter("sridOutput")
451                                .getValue() != null)
452                                || (configuration.getService().getDataProjection().equals(configuration.getService().getParameter("sridInput").getValue()) && configuration
453                                                .getService().getParameter("sridOutput").getValue() != null))
454                {
455                        query = new StringTemplate(configuration.getService().getSQL(1));
456                }
457                // Only sridInput is specified
458                else if ((configuration.getService().getParameter("sridInput").getValue() != null && configuration.getService().getParameter("sridOutput")
459                                .getValue() == null)
460                                || (configuration.getService().getParameter("sridInput").getValue() != null && configuration.getService().getDataProjection().equals(
461                                                configuration.getService().getParameter("sridOutput").getValue())))
462                {
463                        query = new StringTemplate(configuration.getService().getSQL(2));
464                }
465                // sridInput and sridOuput are specified
466                else if (configuration.getService().getParameter("sridInput").getValue() != null
467                                && configuration.getService().getParameter("sridOutput").getValue() != null)
468                {
469                        query = new StringTemplate(configuration.getService().getSQL(3));
470                }
471                return query;
472        }
473
474        /**
475         * <p>This function is used by TSP service.
476         * It converts an array of Point object into a String SQL request
477         * </p>
478         * @param steps an array of Point object
479         * @return a String variable
480         */
481        public String pointsToString(Point steps[])
482        {
483                StringTemplate query;
484                int bboxSize = Integer.parseInt(configuration.getService().getParameter("bbox").getValue());
485                String res = "";
486                for (int i = 0; i < steps.length; i++)
487                {
488                        if (configuration.getService().getParameter("sridInput").getValue() == null
489                                        || configuration.getService().getParameter("sridInput").getValue().equals(configuration.getService().getDataProjection()))
490                        {
491                                query = new StringTemplate(configuration.getService().getParameter("findVertex").getValue());
492                        }
493                        else
494                        {
495                                query = new StringTemplate(configuration.getService().getParameter("findVertexTransf").getValue());
496                        }
497                        query.setAttribute("bbox", bboxSize);
498                        query.setAttribute("sonPx", steps[i].getX());
499                        query.setAttribute("sonPy", steps[i].getY());
500                        query.setAttribute("sridProvider", configuration.getService().getDataProjection());
501                        query.setAttribute("sridIn", configuration.getService().getParameter("sridInput").getValue());
502                        query.setAttribute("sridOut", configuration.getService().getParameter("sridOutput").getValue());
503                        if (i < steps.length - 1)
504                                res += query.toString() + ",";
505                        else
506                                res += query.toString();
507                }
508                return res;
509        }
510        /**
511         * Loads a file
512         * @param f a file object
513         * @return the contain of the file into a String variable
514         */
515        public String loadFile(File f)
516        {
517                try
518                {
519                        BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
520                        StringWriter out = new StringWriter();
521                        int b;
522                        while ((b = in.read()) != -1)
523                                out.write(b);
524                        out.flush();
525                        out.close();
526                        in.close();
527                        return out.toString();
528                }
529                catch (IOException ie)
530                {
531                        ie.printStackTrace();
532                }
533                return null;
534        }
535       
536        /**
537         * Fills a string template
538         * @param resultSet
539         * @param format
540         * @param template
541         * @param reqId
542         * @return
543         * @throws SQLException
544         */
545        public String fillTemplate(ResultSet resultSet, String format, StringTemplate template, String reqId) throws SQLException
546        {
547                ArrayList<Edge> edges = new ArrayList<Edge>();
548                StringTemplate st = template.getInstanceOf();
549               
550                st.setAttribute("request_id", reqId);
551               
552                int k = 0;
553
554                while (resultSet != null && resultSet.next())
555                {
556                    Edge edge = new Edge();
557                    edge.setIid(k);
558                    edge.setGid(resultSet.getInt("gid"));
559
560                       
561                    String[] wkts = parseWKT(resultSet);
562                                               
563                        for (int i = 0; i < wkts.length; i++)
564                        {
565                                String wkt2[] = wkts[i].split(",");
566                                for (int j = 0; j < wkt2.length; j++)
567                                {
568                                        Point point = new Point();
569                                        point.setX(new BigDecimal(wkt2[j].split(" ")[0]));
570                                        point.setY(new BigDecimal(wkt2[j].split(" ")[1]));
571                                        edge.addPoint(point);
572                                }
573
574                        }
575                       
576                        edges.add(edge);
577                        ++k;
578                }
579                st.setAttribute("edges", edges);
580
581                return st.toString();
582        }
583
584        /**
585         * Parses a WKT geometry string to an array
586         * @param resultSet
587         * @return
588         * @throws SQLException
589         */
590        private String[] parseWKT(ResultSet resultSet)
591                        throws SQLException {
592                String wkt = resultSet.getString("wkt");
593                String wkts[] = null;
594               
595                if(wkt.contains("MULTILINESTRING"))
596                {
597                        wkt = wkt.split("MULTILINESTRING\\(\\(")[1].split("\\)\\)")[0];
598                        wkts = wkt.split("\\)\\(");
599                }
600                else if(wkt.contains("POINT"))
601                {
602                        wkts = wkt.split("POINT\\(\\(")[1].split("\\)\\)");
603                }               
604                else if(wkt.contains("LINESTRING"))
605                {
606                        wkts = wkt.split("LINESTRING\\(\\(")[1].split("\\)\\)");
607                }               
608               
609                return wkts;
610        }       
611}
Note: See TracBrowser for help on using the browser.