root/tools/routingservice/branches/wrs-2.0/src/handler/PgRoutingHandler.java @ 306

Revision 306, 8.5 KB (checked in by anton, 17 months ago)

Geometry transformation added

Line 
1/*  WRS 2.0
2 *  Copyright (C) 2009 Anton Patrushev
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18package handler;
19
20import geometry.Point;
21
22import java.math.BigDecimal;
23import java.sql.Connection;
24import java.sql.ResultSet;
25import java.sql.SQLException;
26import java.sql.Statement;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.Enumeration;
30import java.util.HashMap;
31import java.util.Hashtable;
32import java.util.Iterator;
33import java.util.Vector;
34
35import model.Resource;
36import model.Service;
37import util.Log;
38import util.ObjectPool;
39import util.Parameter;
40import util.ServiceRequest;
41import util.db.JDBCConnectionPool;
42
43import org.antlr.stringtemplate.StringTemplate;
44import org.opengis.geometry.MismatchedDimensionException;
45import org.opengis.referencing.FactoryException;
46import org.opengis.referencing.NoSuchAuthorityCodeException;
47import org.opengis.referencing.operation.TransformException;
48
49import com.vividsolutions.jts.io.ParseException;
50
51public class PgRoutingHandler extends ResourceHandler
52{
53        private Resource resource;
54        private Hashtable<String, String> functions;
55
56        public static final String SRID = "srid";
57        public static final String UNITS = "units";
58
59        public static final String FUNCTION = "function";
60        public static final String INPUT = "input";
61        public static final String OUTPUT = "output";
62
63        // Arrays in Services enum's elements specify an order of parameters
64        private enum Services
65        {
66                ROUTE
67                {
68                        ArrayList getParameters()
69                        {
70                                String[] p = { "table", "x1", "y1", "x2", "y2", "box",
71                                                "cost_value", "reverse_cost_value", "directed", "hasrc" };
72                                return new ArrayList(Arrays.asList(p));
73                        }
74                },
75                CATCH
76                {
77                        ArrayList getParameters()
78                        {
79                                String[] p = { "table", "x1", "y1", "distance", "rbox",
80                                                "cost_value", "reverse_cost_value", "directed", "hasrc" };
81                                return new ArrayList(Arrays.asList(p));
82                        }
83                };
84
85                abstract ArrayList getParameters();
86        }
87
88        public PgRoutingHandler()
89        {
90                // TODO implement reading functions mapping from a config file
91                this.functions = new Hashtable<String, String>();
92                this.functions.put("route", "shootingstar_sp_smart");
93                this.functions.put("travel", "tsp_astar_directed_smart");
94                this.functions.put("catch", "driving_distance");
95        }
96
97        @Override
98        public ArrayList<HashMap<String, Parameter>> handleRequest(
99                        ServiceRequest request, Log log)
100        {
101                ArrayList<HashMap<String, Parameter>> out = new ArrayList<HashMap<String, Parameter>>();
102
103                if (this.resource != null)
104                {
105
106                        String query = fillQueryTemplate(this.resource.getQuery(), request
107                                        .getService(), request.getParameters());
108
109                        System.out.println("Query:" + query);
110
111                        ObjectPool<Connection> pool = this.resource.getPool();
112                        Connection con = pool.checkOut();
113
114                        if (con != null)
115                        {
116
117                                // TODO send query and get a result
118                                try
119                                {
120                                        Statement stmt = con.createStatement();
121                                        ResultSet result = stmt.executeQuery(query);
122
123                                        while (result.next())
124                                        {
125                                                Iterator<String> keys = request.getService().getOut()
126                                                                .keySet().iterator();
127                                                HashMap<String, Parameter> paraMap = new HashMap<String, Parameter>();
128                                                while (keys.hasNext())
129                                                {
130                                                        String key = keys.next();
131                                                        Parameter op = new Parameter();
132                                                        op.setName(key);
133                                                        op.setType(request.getService().getOut().get(key)
134                                                                        .getType());
135                                                        op.setValue(result.getString(key));
136
137                                                        paraMap.put(key, op);
138                                                }
139                                                out.add(paraMap);
140                                        }
141
142                                }
143                                catch (SQLException e)
144                                {
145                                        // TODO Auto-generated catch block
146                                        e.printStackTrace();
147                                }
148
149                                pool.checkIn(con);
150                        }
151                        else
152                        {
153                                // Connection pool is full
154                                log.logger.severe("Connection to " + resource.getUrl()
155                                                + " failed.");
156                        }
157                }
158                return out;
159        }
160
161        @Override
162        public void setResource(Resource resource)
163        {
164                this.resource = resource;
165        }
166
167        @Override
168        public String fillQueryTemplate(String template, Service service,
169                        HashMap<String, Parameter> parameters)
170        {
171                StringTemplate query = new StringTemplate(template);
172                String function = this.functions.get(service.getName());
173                query.setAttribute(FUNCTION, function);
174
175                // fill output
176                StringBuffer output = new StringBuffer("");
177                Iterator<String> opit = service.getOut().keySet().iterator();
178                while (opit.hasNext())
179                {
180                        try
181                        {
182                                String key = opit.next();
183                                Parameter p = this.resource.getParameters().get(key);
184                                output.append(p.getKey()).append(" as ").append(p.getName());
185                                if (opit.hasNext())
186                                        output.append(",");
187                        }
188                        catch (NullPointerException e)
189                        {
190                                // Required parameter is missing!
191                                // TODO do something smart here
192                        }
193                }
194                query.setAttribute(OUTPUT, output.toString());
195
196                StringBuffer params = new StringBuffer("");
197
198                // fill parameters
199                // Iterator<String> keys = service.getIn().keySet().iterator();
200                Iterator<String> keys = Services.valueOf(
201                                service.getName().toUpperCase()).getParameters().iterator();
202                while (keys.hasNext())
203                {
204                        try
205                        {
206                                String key = keys.next();
207
208                                Parameter p = parameters.get(key);
209                                String value = p.getValue();
210
211                                // Check if we need to re-project coordinates
212                                if (p.getType().toLowerCase().equals(DOUBLE)
213                                                && key.toLowerCase().startsWith("x"))
214                                {
215                                        try
216                                        {
217                                                int srid_in = Integer.parseInt(parameters
218                                                                .get("srid_in").getValue());
219                                                int srid_out = Integer.parseInt(resource
220                                                                .getParameters().get("srid").getValue());
221
222                                                if (srid_in != srid_out)
223                                                {
224                                                        // try to find Y coordinate
225                                                        String yKey = key.toLowerCase().replaceFirst("x",
226                                                                        "y");
227                                                        Parameter yP = parameters.get(yKey);
228                                                        String yValue = yP.getValue();
229                                                        String[] transformed = transformPoint(value, yValue,
230                                                                        srid_in, srid_out);
231                                                        p.setValue(transformed[0]);
232                                                        yP.setValue(transformed[1]);
233                                                }
234                                        }
235                                        catch (NullPointerException e)
236                                        {
237                                                //Can't find srid_in or srid_out
238                                                //Do nothing
239                                        }
240                                        catch (MismatchedDimensionException e)
241                                        {
242                                                // TODO Auto-generated catch block
243                                                e.printStackTrace();
244                                        }
245                                        catch (NoSuchAuthorityCodeException e)
246                                        {
247                                                // TODO Auto-generated catch block
248                                                e.printStackTrace();
249                                        }
250                                        catch (FactoryException e)
251                                        {
252                                                // TODO Auto-generated catch block
253                                                e.printStackTrace();
254                                        }
255                                        catch (ParseException e)
256                                        {
257                                                // TODO Auto-generated catch block
258                                                e.printStackTrace();
259                                        }
260                                        catch (TransformException e)
261                                        {
262                                                // TODO Auto-generated catch block
263                                                e.printStackTrace();
264                                        }
265                                }
266
267                                if (p.getType().toLowerCase().equals(STRING))
268                                {
269                                        value = "'" + value + "'";
270                                }
271                                params.append(value);
272
273                                if (keys.hasNext())
274                                        params.append(",");
275
276                        }
277                        catch (NullPointerException e)
278                        {
279                                // Required parameter is missing!
280                                // TODO do something smart here
281                        }
282                }
283
284                query.setAttribute(INPUT, params.toString());
285
286                return query.toString();
287        }
288
289        @Override
290        public boolean checkService(Service service)
291        {
292                return this.resource.getServices().containsKey(service.getName());
293        }
294
295        @Override
296        public ArrayList<Point> parseGeometry(String geom)
297        {
298                ArrayList<Point> points = new ArrayList<Point>();
299                String[] wkts = parseWKT(geom);
300
301                for (int i = 0; i < wkts.length; i++)
302                {
303                        String wkt2[] = wkts[i].split(",");
304                        for (int j = 0; j < wkt2.length; j++)
305                        {
306                                Point point = new Point();
307                                point.setX(Double.parseDouble(wkt2[j].split(" ")[0]));
308                                point.setY(Double.parseDouble(wkt2[j].split(" ")[1]));
309                                points.add(point);
310                        }
311
312                }
313                return points;
314        }
315
316        /**
317         * Parses a WKT geometry string to an array
318         *
319         * @param resultSet
320         * @return
321         * @throws SQLException
322         */
323        private String[] parseWKT(String wkt)
324        {
325                String wkts[] = null;
326
327                if (wkt.contains("MULTILINESTRING"))
328                {
329                        wkt = wkt.split("MULTILINESTRING\\(\\(")[1].split("\\)\\)")[0];
330                        wkts = wkt.split("\\)\\(");
331                }
332                else if (wkt.contains("POINT"))
333                {
334                        wkts = wkt.split("POINT\\(\\(")[1].split("\\)\\)");
335                }
336                else if (wkt.contains("LINESTRING"))
337                {
338                        wkts = wkt.split("LINESTRING\\(\\(")[1].split("\\)\\)");
339                }
340                else if (wkt.contains("POLYGON"))
341                {
342                        wkts = wkt.split("POLYGON\\(\\(")[1].split("\\)\\)");
343                }
344
345                return wkts;
346        }
347
348}
Note: See TracBrowser for help on using the browser.