diff options
Diffstat (limited to 'chimere/route.py')
-rw-r--r-- | chimere/route.py | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/chimere/route.py b/chimere/route.py new file mode 100644 index 0000000..8c4638a --- /dev/null +++ b/chimere/route.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +""" +Routing management +""" + +import os, re, shutil, tempfile +from BeautifulSoup import BeautifulSoup +from subprocess import Popen, PIPE +from django.contrib.gis.gdal import DataSource +from django.contrib.gis.gdal.error import OGRException + +from django.conf import settings + +class Router: + def route(self, lon1, lat1, lon2, lat2, transport='foot'): + ''' + Get a list of geojson polylines + ''' + return [] + +class RoutinoRouter(Router): + re_desc = [re.compile("<tr class='n'>"), re.compile("<tr class='s'>"), + re.compile("<tr class='t'>")] + def route(self, lon1, lat1, lon2, lat2, steps=[], transport='foot', + speed=None): + ''' + Get a list of geojson polylines and route description + ''' + language = settings.LANGUAGE_CODE.split('-')[0] + args = [settings.CHIMERE_ROUTING_ENGINE['PATH'], + "--dir=%s" % settings.CHIMERE_ROUTING_ENGINE['DB_PATH'], + "--transport=%s" % transport, + "--language=%s" % language, + "--shortest", + "--output-html", + "--output-gpx-track", + "--lat1=%0.15f" % lat1, + "--lon1=%0.15f" % lon1, + ] + if speed: + args += ["--speed-%s=%s" % (highway, unicode(speed)) + for highway in ('motorway', 'trunk', 'primary', 'secondary', + 'tertiary', 'unclassified', 'residential', 'service', + 'track','cycleway','path','steps')] + lonlat_index = 1 + for lon, lat in steps: + lonlat_index += 1 + args += ["--lat%d=%0.15f" % (lonlat_index, lat), + "--lon%d=%0.15f" % (lonlat_index, lon)] + lonlat_index += 1 + args += ["--lat%d=%0.15f" % (lonlat_index, lat2), + "--lon%d=%0.15f" % (lonlat_index, lon2)] + tmp_dir = tempfile.mkdtemp(prefix='chimere_') + os.sep + p = Popen(args, stdout=PIPE, cwd=tmp_dir) + p.communicate() + try: + ds = DataSource(tmp_dir + 'shortest-track.gpx') + except OGRException: + return [], None, None + if not ds: + return [], None, None + layer = ds[0] + trk_layer = None + for layer in ds: + if layer.name == 'tracks': + trk_layer = layer + break + multilines = trk_layer.get_geoms() + res = [] + for multiline in multilines: + res += [geom.geojson for geom in multiline] + desc = [] + # only keeping interessant lines of the desc + for line in open(tmp_dir + 'shortest.html').readlines(): + if [True for r in self.re_desc if r.match(line)]: + desc.append(BeautifulSoup(line).prettify()) + total = self.webify(desc[-1]) + desc = desc[1:-2] + # very fragile piece of code but only break the numerotation + number_tpl = '<tr class="n"><span class="number">%d.</span>' + desc = [re.sub('<tr class="n">', number_tpl % (idx/2+1), d) + if idx % 2 else d + for idx, d in enumerate(desc)] + desc = self.webify(BeautifulSoup('\n'.join(desc)).prettify()) + desc = re.sub(" \[", "", desc) + desc = re.sub(" \]", "", desc) + shutil.rmtree(tmp_dir) + return res, desc, total + + @staticmethod + def webify(lbl): + lbl = re.sub("<td", "<span", lbl) + lbl = re.sub("</td>", "</span>", lbl) + lbl = re.sub("</tr>", "</div>", lbl) + lbl = re.sub("<tr", "<div", lbl) + return lbl + +router = None +if hasattr(settings, 'CHIMERE_ROUTING_ENGINE') and \ + settings.CHIMERE_ROUTING_ENGINE['ENGINE'] == 'routino': + router = RoutinoRouter() + |