Commit 188aaf6a authored by jben's avatar jben

this is a commit

parent 650ca509
secret.py
*.out
*.mc
html {
min-height: 100%;
position: relative;
}
body {
margin: 0;
width: 100%;
height: 100%;
}
div#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: calc(100% - 300px);
}
div#parameters {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
color: black;
font-size: 75%;
background-color: white;
position: absolute;
top: 0px;
right: 0px;
width: 300px;
height: 100%;
padding: 10px;
z-index: 5;
}
div#advanced_parameters {
}
This diff is collapsed.
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
.leaflet-control {
display: inline;
}
.leaflet-popup-tip {
width: 21px;
_width: 27px;
margin: 0 auto;
_margin-top: -3px;
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
}
.leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
border: 1px solid #999;
}
.leaflet-popup-content-wrapper {
zoom: 1;
}
.leaflet-control-zoom,
.leaflet-control-layers {
border: 3px solid #999;
}
.leaflet-control-layers-toggle {
}
.leaflet-control-attribution,
.leaflet-control-layers,
.leaflet-control-scale-line {
background: white;
}
.leaflet-zoom-box {
filter: alpha(opacity=50);
}
.leaflet-control-attribution {
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
}
.leaflet-label {
background: rgb(235, 235, 235);
background: rgba(235, 235, 235, 0.81);
background-clip: padding-box;
border-color: #777;
border-color: rgba(0,0,0,0.25);
border-radius: 4px;
border-style: solid;
border-width: 4px;
color: #111;
display: block;
font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: bold;
padding: 1px 6px;
position: absolute;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
z-index: 6;
}
.leaflet-label.leaflet-clickable {
cursor: pointer;
}
.leaflet-label:before {
border-right: 6px solid black;
border-right-color: inherit;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
content: "";
position: absolute;
top: 5px;
left: -10px;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hervé</title>
<link rel="stylesheet" href="css/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="css/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="css/leaflet.label.css" />
<link rel="stylesheet" type="text/css" href="css/herve.css" />
</head>
<body>
<div id="map"></div>
<div id="parameters">
<div id="logo">
<p align="center"><img src="images/herve.png"/></p>
<p align="right">Dessin par
<a href="http://kamsblog.org">Kam</a>,
<a href="http://creativecommons.org/licenses/by-sa/3.0/">CC BY-SA 3.0</a></p>
<hr />
</div>
<div id="recherche">
<form id="recherche" onsubmit="rechercher();return false;">
<input type="text" name="recherche_txt" size="20" id="recherche_txt" />
<input type="button" onclick="rechercher();return false;" value="Rechercher"/>
</form>
<div id="recherche_results"></div>
<hr />
</div>
<form id="route" onsubmit="comput(); return false;">
Masse roulante&nbsp;:
<input type="text" name="mass" value="90" id="mass" size="3" onchange="mettreAJourStatus();" /> kg
<a href="#" onclick="help('mass'); return false;">infos</a>
<br />
Vitesse sur le plat&nbsp;:
<input type="text" name="speedref" value="20" id="speedref" size="3" onchange="mettreAJourStatus();" /> km/h
<a href="#" onclick="help('speedref'); return false;">infos</a>
<br />
<div id="advanced_parameters">
Mode d'optimisation&nbsp;:
<ul>
<li><input type="radio" id="mode" name="mode" value="e" checked onchange="mettreAJourStatus();" />Energie
fournie par le cycliste <a href="#" onclick="help('modee'); return false;">infos</a></li>
<li><input type="radio" id="mode" name="mode" value="d" onchange="mettreAJourStatus();" />Distance
totale parcourue <a href="#" onclick="help('moded'); return false;">infos</a></li>
<li><input type="radio" id="mode" name="mode" value="p" onchange="mettreAJourStatus();" />Dénivelé
ascendant cumulé <a href="#" onclick="help('modep'); return false;">infos</a></li>
</ul>
<br />
SCx&nbsp;:
<input type="text" name="SCx" value="0.45" id="SCx" size="5" onchange="mettreAJourStatus();" /> m^2
<a href="#" onclick="help('SCx'); return false;">infos</a>
<br />
Cr&nbsp;
<input type="text" name="Cr" value="0.008" id="Cr" size="6" onchange="mettreAJourStatus();" />
<a href="#" onclick="help('Cr'); return false;">infos</a>
<br />
Vent&nbsp;:
<input type="text" name="winddir" value="0" id="winddir" size="3" onchange="mettreAJourStatus();" /> deg Nord&nbsp;;
<input type="text" name="windspeed" value="0" id="windspeed" size="3" onchange="mettreAJourStatus();" /> km/h
<a href="#" onclick="help('wind'); return false;">infos</a>
</div>
</form>
<div id="advanced_parameters_txt"></div>
<hr />
<div id="global_results"></div>
<div id="help"></div>
<div id="status"></div>
</div>
<script src="js/leaflet.js"></script>
<script src="js/leaflet.label.js"></script>
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/herve.js"></script>
</body>
</html>
This diff is collapsed.
../images
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
(c) 2012-2013, Jacob Toye, Smartrak
https://github.com/Leaflet/Leaflet.label
http://leafletjs.com
https://github.com/jacobtoye
*/
(function(){L.labelVersion="0.1.4-dev",L.Label=L.Popup.extend({includes:L.Mixin.Events,options:{autoPan:!1,className:"",clickable:!1,closePopupOnClick:!1,noHide:!1,offset:new L.Point(12,-15),opacity:1},onAdd:function(t){this._map=t,this._pane=this._source instanceof L.Marker?t._panes.markerPane:t._panes.popupPane,this._container||this._initLayout(),this._updateContent();var e=t.options.fadeAnimation;e&&L.DomUtil.setOpacity(this._container,0),this._pane.appendChild(this._container),t.on("viewreset",this._updatePosition,this),this._animated&&t.on("zoomanim",this._zoomAnimation,this),L.Browser.touch&&!this.options.noHide&&L.DomEvent.on(this._container,"click",this.close,this),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity)},onRemove:function(t){this._pane.removeChild(this._container),L.Util.falseFn(this._container.offsetWidth),t.off({viewreset:this._updatePosition,zoomanim:this._zoomAnimation},this),t.options.fadeAnimation&&L.DomUtil.setOpacity(this._container,0),this._removeInteraction(),this._map=null},close:function(){var t=this._map;t&&(L.Browser.touch&&!this.options.noHide&&L.DomEvent.off(this._container,"click",this.close),t._label=null,t.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(t){this.options.opacity=t,this._container&&L.DomUtil.setOpacity(this._container,t)},_initLayout:function(){this._container=L.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this.updateZIndex(this._zIndex)},_updateContent:function(){this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content)},_updateLayout:function(){},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_setPosition:function(t){t=t.add(this.options.offset),L.DomUtil.setPosition(this._container,t)},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(e)},_initInteraction:function(){if(this.options.clickable){var t=this._container,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];L.DomUtil.addClass(t,"leaflet-clickable"),L.DomEvent.on(t,"click",this._onMouseClick,this);for(var i=0;e.length>i;i++)L.DomEvent.on(t,e[i],this._fireMouseEvent,this)}},_removeInteraction:function(){if(this.options.clickable){var t=this._container,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];L.DomUtil.removeClass(t,"leaflet-clickable"),L.DomEvent.off(t,"click",this._onMouseClick,this);for(var i=0;e.length>i;i++)L.DomEvent.off(t,e[i],this._fireMouseEvent,this)}},_onMouseClick:function(t){this.hasEventListeners(t.type)&&L.DomEvent.stopPropagation(t),this.fire(t.type,{originalEvent:t})},_fireMouseEvent:function(t){this.fire(t.type,{originalEvent:t}),"contextmenu"===t.type&&this.hasEventListeners(t.type)&&L.DomEvent.preventDefault(t),"mousedown"!==t.type?L.DomEvent.stopPropagation(t):L.DomEvent.preventDefault(t)}}),L.Icon.Default.mergeOptions({labelAnchor:new L.Point(9,-20)}),L.Marker.mergeOptions({icon:new L.Icon.Default}),L.Marker.include({showLabel:function(){return this._label&&this._map&&(this._label.setLatLng(this._latlng),this._map.showLabel(this._label)),this},hideLabel:function(){return this._label&&this._label.close(),this},setLabelNoHide:function(t){this._labelNoHide!==t&&(this._labelNoHide=t,t?(this._removeLabelRevealHandlers(),this.showLabel()):(this._addLabelRevealHandlers(),this.hideLabel()))},bindLabel:function(t,e){var i=L.point(this.options.icon.options.labelAnchor)||new L.Point(0,0);return i=i.add(L.Label.prototype.options.offset),e&&e.offset&&(i=i.add(e.offset)),e=L.Util.extend({offset:i},e),this._labelNoHide=e.noHide,this._label||(this._labelNoHide||this._addLabelRevealHandlers(),this.on("remove",this.hideLabel,this).on("move",this._moveLabel,this),this._hasLabelHandlers=!0),this._label=new L.Label(e,this).setContent(t),this},unbindLabel:function(){return this._label&&(this.hideLabel(),this._label=null,this._hasLabelHandlers&&(this._labelNoHide||this._removeLabelRevealHandlers(),this.off("remove",this.hideLabel,this).off("move",this._moveLabel,this)),this._hasLabelHandlers=!1),this},updateLabelContent:function(t){this._label&&this._label.setContent(t)},getLabel:function(){return this._label},_addLabelRevealHandlers:function(){this.on("mouseover",this.showLabel,this).on("mouseout",this.hideLabel,this),L.Browser.touch&&this.on("click",this.showLabel,this)},_removeLabelRevealHandlers:function(){this.off("mouseover",this.showLabel,this).off("mouseout",this.hideLabel,this),L.Browser.touch&&this.off("click",this.showLabel,this)},_moveLabel:function(t){this._label.setLatLng(t.latlng)},_originalUpdateZIndex:L.Marker.prototype._updateZIndex,_updateZIndex:function(t){var e=this._zIndex+t;this._originalUpdateZIndex(t),this._label&&this._label.updateZIndex(e)},_originalSetOpacity:L.Marker.prototype.setOpacity,setOpacity:function(t,e){this.options.labelHasSemiTransparency=e,this._originalSetOpacity(t)},_originalUpdateOpacity:L.Marker.prototype._updateOpacity,_updateOpacity:function(){var t=0===this.options.opacity?0:1;this._originalUpdateOpacity(),this._label&&this._label.setOpacity(this.options.labelHasSemiTransparency?this.options.opacity:t)}}),L.Path.include({bindLabel:function(t,e){return this._label&&this._label.options===e||(this._label=new L.Label(e,this)),this._label.setContent(t),this._showLabelAdded||(this.on("mouseover",this._showLabel,this).on("mousemove",this._moveLabel,this).on("mouseout remove",this._hideLabel,this),L.Browser.touch&&this.on("click",this._showLabel,this),this._showLabelAdded=!0),this},unbindLabel:function(){return this._label&&(this._hideLabel(),this._label=null,this._showLabelAdded=!1,this.off("mouseover",this._showLabel,this).off("mousemove",this._moveLabel,this).off("mouseout remove",this._hideLabel,this)),this},updateLabelContent:function(t){this._label&&this._label.setContent(t)},_showLabel:function(t){this._label.setLatLng(t.latlng),this._map.showLabel(this._label)},_moveLabel:function(t){this._label.setLatLng(t.latlng)},_hideLabel:function(){this._label.close()}}),L.Map.include({showLabel:function(t){return this._label=t,this.addLayer(t)}}),L.FeatureGroup.include({clearLayers:function(){return this.unbindLabel(),this.eachLayer(this.removeLayer,this),this},bindLabel:function(t,e){return this.invoke("bindLabel",t,e)},unbindLabel:function(){return this.invoke("unbindLabel")},updateLabelContent:function(t){this.invoke("updateLabelContent",t)}})})(this,document);
\ No newline at end of file
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
from secret import dbstr
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT cum_elev,energy,dist,mean_speed,time FROM rv_jobs WHERE jid=%s;",(jid,))
if cur.rowcount<1:
sys.exit(1)
ligne=cur.fetchone()
cum_elev=ligne[0]
energy=ligne[1]
dist=ligne[2]
mean_speed=ligne[3]
time=ligne[4]
cum_elev=int(round(cum_elev))
energy=int(round(energy/1000))
dist=int(round(dist))*1./1000
mean_speed=round(mean_speed*36)/10
tmin=time/60
time=("%dh%02d" % (int(tmin/60),int(tmin%60)))
print "Content-type: application/json\n"
print json.dumps({'cum_elev':cum_elev,'energy':energy,'dist':dist,'mean_speed':mean_speed,'time':time})
sys.stdout.flush()
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
import rv
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
markers = rv.getMarkers(jid)
print "Content-type: application/json\n"
print json.dumps(markers);
sys.stdout.flush()
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
import rv
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
params = rv.getParameters(jid)
print "Content-type: application/json\n"
print json.dumps(params);
sys.stdout.flush()
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
import rv
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
points = rv.getPoints(jid)
bounds = [
[min(map(lambda x:x.lat,points)), min(map(lambda x:x.lon,points))],
[max(map(lambda x:x.lat,points)), max(map(lambda x:x.lon,points))]
]
allres = [
rv.getFeatColl(points,3200,simplify=True),
rv.getFeatColl(points,1600,simplify=True),
rv.getFeatColl(points,800,simplify=True),
rv.getFeatColl(points,400),
rv.getFeatColl(points,200),
rv.getFeatColl(points,100),
rv.getFeatColl(points,50),
rv.getFeatColl(points,25),
];
print "Content-type: application/json\n"
print json.dumps({'allres':allres,'bounds':bounds});
sys.stdout.flush()
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
from secret import dbstr
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT state,status FROM rv_jobs WHERE jid=%s;",(jid,));
ligne=cur.fetchone()
state=ligne[0]
status=ligne[1]
print "Content-type: application/json\n"
print json.dumps({'State':state,'Status':status})
sys.stdout.flush()
#!/usr/bin/python
import cgi
import cgitb
import sys
import psycopg2
import json
import subprocess
#cgitb.enable(display=0, logdir="/tmp/hervelog/")
cgitb.enable()
from secret import dbstr
form = cgi.FieldStorage()
try:
jid=int(form['jid'].value)
except (KeyError, ValueError):
sys.exit(1)
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT state,pid FROM rv_jobs WHERE jid=%s;",(jid,));
ligne=cur.fetchone()
state=ligne[0]
pid=ligne[1]
if(state!=1 and state!=2):
print "Content-type: application/json\n"
print json.dumps({})
if(pid>0):
subprocess.Popen(['/bin/kill',"%u"%pid]);
cur.execute("UPDATE rv_jobs SET state=99 WHERE jid=%s;",(jid,));
cur.close()
db.commit()
db.close()
print "Content-type: application/json\n"
print json.dumps({'jid':0})
sys.stdout.flush()
#!/usr/bin/python
import psycopg2
import sys
import numpy as np
import colorsys
from secret import dbstr
class Node:
"""node with routing information
Node infos :
id: node id in the OSM database
lon: longitude
lat: latitude
height: height obtained by bi-linear interpolation from SRTM data
Routing infos :
speed: speed in km/h at this node
dist: travelled distance in meters from the beginning
cum_elev: cumulated elevation in meter from the begining
energy: supplied energy in Joules from the begining
time: elpased time in seconds from the begining
"""
def __init__(self, lon, lat, height, speed, dist, cum_elev, energy, time):
self.lon, self.lat, self.height = lon, lat, height
self.speed, self.dist, self.cum_elev = speed, dist, cum_elev
self.energy, self.time = energy, time
def __repr__(self):
return "\n" +\
"node(\n" +\
" lon = %f,\n" % self.lon +\
" lat = %f,\n" % self.lat +\
" height = %f,\n" % self.height +\
" speed = %f,\n" % self.speed +\
" dist = %f,\n" % self.dist +\
" cum_elev = %f,\n" % self.cum_elev +\
" energy = %f,\n" % self.energy +\
" time = %f\n" % self.time +\
" )\n"
def fcolor(pente):
repere=.05
if(pente > -repere and pente<repere):
col=colorsys.hsv_to_rgb((1.-pente/repere)/6,1,.8)
elif(pente>=repere and pente<2*repere):
col=colorsys.hsv_to_rgb(0,1,.8*(2-pente/repere))
elif(pente>=2*repere):
col=colorsys.hsv_to_rgb(0,1,0)
else:
col=colorsys.hsv_to_rgb(1./3,1,.8)
return "#%02x%02x%02x" % tuple(map(lambda x:int(255*x+.5),col))
def getParameters(jid):
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT mass,speedref,scx,cr,winddir,windspeed,criterion FROM rv_jobs WHERE jid=%s;",(jid,))
if cur.rowcount<1:
return None
ligne=cur.fetchone()
return {
'mass':ligne[0],
'speedref':ligne[1],
'SCx':ligne[2],
'Cr':ligne[3],
'winddir':ligne[4],
'windspeed':ligne[5],
'criterion':ligne[6]
}
def getMarkers(jid):
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT ST_X(geom),ST_Y(geom) FROM rv_waypoints WHERE jid=%s ORDER BY rank;",(jid,))
if cur.rowcount<1:
return None
markers = []
for ligne in cur:
markers.append([ligne[1],ligne[0]])
return markers
def getPoints(jid):
db = psycopg2.connect(dbstr)
cur = db.cursor()
cur.execute("SELECT ST_X(geom),ST_Y(geom),height,speed,dist,cum_elev,energy,time FROM rv_results WHERE jid=%s ORDER BY rank;",(jid,))
if cur.rowcount<1:
return None
lPoints=[]
for ligne in cur:
n=Node(
lon=ligne[0],
lat=ligne[1],
height=ligne[2],
speed=ligne[3],
dist=ligne[4],
cum_elev=ligne[5],
energy=ligne[6],
time=ligne[7]
)
lPoints.append(n)
cur.close()
db.close()
return lPoints
def getFeatColl(lPoints_ref,pas,simplify=False):
lPoints = lPoints_ref[:]
llPoints=[]
lastpts=lPoints.pop(0)
enCours=[lastpts]
i=0
while True:
# on construit de i*pas a (i+1)*pas
# on ajoute les points du segment
while lPoints[0].dist<(i+1)*pas:
lastpts=lPoints.pop(0)
enCours.append(lastpts)
if(len(lPoints)==0):
llPoints.append(enCours)
break
if(len(lPoints)==0):
break
# on cree un pts
pts=lPoints[0]
r=((i+1)*pas-lastpts.dist)/(pts.dist-lastpts.dist)
s=1-r
# npts=r*pts+s*lastpts
npts = Node(
lon = r*pts.lon+s*lastpts.lon,
lat = r*pts.lat+s*lastpts.lat,
height = r*pts.height+s*lastpts.height,
speed = np.sqrt(r*np.power(pts.speed,2)+s*np.power(lastpts.speed,2)),
dist = r*pts.dist+s*lastpts.dist,
cum_elev = r*pts.cum_elev + s*lastpts.cum_elev,
energy = r*pts.energy + s*lastpts.energy,
time = r*pts.time + s*lastpts.time
)
enCours.append(npts)
llPoints.append(enCours)
enCours=[npts]
i+=1
kmax=int(round(4.*(65./pas)*(65./pas)+1))
a=np.array([1.])
a0=np.array([0.])
for k in range(1,kmax):
a=(np.concatenate((a,a0))+np.concatenate((a0,a)))/2
fpente = lambda a:(a[-1].height-a[0].height)/(a[-1].dist-a[0].dist)