Skip to content

Commit

Permalink
second test using 3d segments, see also issue Project-OSRM#271, much …
Browse files Browse the repository at this point in the history
…too slow at the moment
  • Loading branch information
Jens Thiele committed Dec 10, 2012
1 parent 8247246 commit aeb7927
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 36 deletions.
96 changes: 62 additions & 34 deletions Extractor/ExtractionContainers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

#include "ExtractionContainers.h"

void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) {

void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM, lua_State *myLuaState) {
try {
unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0;
Expand Down Expand Up @@ -221,43 +222,70 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const

double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon);
assert(edgeIT->speed != -1);
double weight = ( distance * 10. ) / (edgeIT->speed / 3.6);
int intWeight = std::max(1, (int)std::floor((edgeIT->isDurationSet ? edgeIT->speed : weight)+.5) );

double weight[2];
// todo: call only once
// - need multiple return (weight forward, weight backward, distance)
try {
weight[0]=luabind::call_function<double>(myLuaState,
"segment_function",
edgeIT->startCoord.lat, edgeIT->startCoord.lon,
edgeIT->targetCoord.lat, edgeIT->targetCoord.lon,
edgeIT->speed,
distance);
weight[1]=luabind::call_function<double>(myLuaState,
"segment_function",
edgeIT->targetCoord.lat, edgeIT->targetCoord.lon,
edgeIT->startCoord.lat, edgeIT->startCoord.lon,
edgeIT->speed,
distance);
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
std::cerr << "-- " << lua_tostring(Ler, -1) << std::endl;
lua_pop(Ler, 1); // remove error message
ERR(er.what());
}
catch (...) {
ERR("Unknown error!");
}

int intDist = std::max(1, (int)distance);
short zero = 0;
short one = 1;

fout.write((char*)&edgeIT->start, sizeof(unsigned));
fout.write((char*)&edgeIT->target, sizeof(unsigned));
fout.write((char*)&intDist, sizeof(int));
switch(edgeIT->direction) {
case _Way::notSure:
fout.write((char*)&zero, sizeof(short));
break;
case _Way::oneway:
fout.write((char*)&one, sizeof(short));
break;
case _Way::bidirectional:
fout.write((char*)&zero, sizeof(short));

break;
case _Way::opposite:
fout.write((char*)&one, sizeof(short));
break;
default:
cerr << "[error] edge with no direction: " << edgeIT->direction << endl;
assert(false);
break;
}
fout.write((char*)&intWeight, sizeof(int));
assert(edgeIT->type >= 0);
fout.write((char*)&edgeIT->type, sizeof(short));
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
// note: maybe 2 half-edges!
bool oneway = (weight[0]!=weight[1])
|| (edgeIT->direction == _Way::oneway)
|| (edgeIT->direction == _Way::opposite);
switch(edgeIT->direction) {
case _Way::notSure:
case _Way::oneway:
case _Way::bidirectional:
case _Way::opposite:
break;
default:
cerr << "[error] edge with no direction: " << edgeIT->direction << endl;
assert(false);
break;
}
for (int i=0; i<((weight[0]==weight[1])||(edgeIT->direction == _Way::oneway)||(edgeIT->direction == _Way::opposite) ? 1 : 2); ++i) {
fout.write((char*)((i==0) ? &edgeIT->start : &edgeIT->target), sizeof(unsigned));
fout.write((char*)((i==0) ? &edgeIT->target : &edgeIT->start), sizeof(unsigned));
fout.write((char*)&intDist, sizeof(int));
if (oneway)
fout.write((char*)&one, sizeof(short));
else
fout.write((char*)&zero, sizeof(short));
int intWeight = std::max(1, (int)std::floor((edgeIT->isDurationSet ? edgeIT->speed : weight[i])+.5) );
fout.write((char*)&intWeight, sizeof(int));
assert(edgeIT->type >= 0);
fout.write((char*)&edgeIT->type, sizeof(short));
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
++usedEdgeCounter;
}
}
++usedEdgeCounter;
++edgeIT;
}
}
Expand Down
9 changes: 8 additions & 1 deletion Extractor/ExtractionContainers.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
#include "ExtractorStructs.h"
#include "../DataStructures/Util.h"

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>

class ExtractionContainers {
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
Expand Down Expand Up @@ -55,7 +62,7 @@ class ExtractionContainers {
wayStartEndVector.clear();
}

void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM);
void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM, lua_State *myLuaState);

STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
Expand Down
5 changes: 5 additions & 0 deletions createHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ int main (int argc, char *argv[]) {

// Create a new lua state
lua_State *myLuaState = luaL_newstate();
#if LUA_VERSION_NUM >= 501
luaL_openlibs(myLuaState);
#else
lua_baselibopen(myLuaState);
#endif

// Connect LuaBind to this lua state
luabind::open(myLuaState);
Expand Down
3 changes: 2 additions & 1 deletion extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ int main (int argc, char *argv[]) {
parser->Parse();
INFO("parsing finished after " << get_timestamp() - time << " seconds");

externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM);
// todo
externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM, scriptingEnvironment.luaStateVector[0]);

stringMap.clear();
delete parser;
Expand Down
80 changes: 80 additions & 0 deletions profiles/bicycle.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
-- Begin of globals
require("curl")
require("json")
clib = curl.easy_init()

barrier_whitelist = { [""] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true}
access_tag_whitelist = { ["yes"] = true, ["permissive"] = true, ["designated"] = true }
access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestery"] = true }
Expand Down Expand Up @@ -258,3 +262,79 @@ function way_function (way, numberOfNodesInWay)
way.type = 1
return 1
end

function map(func, array)
local new_array = {}
for i,v in ipairs(array) do
new_array[i] = func(v)
end
return new_array
end

function params(pl,dist)
return 'path='..table.concat(map(function(x) return table.concat(x,",") end, pl),"|")..'&upsample='..dist..'&format=sjs'
end

-- input: 2d polyline
-- output: upsampled 4d polyline with elevation and wgs84-distance from startpoint as 3rd and 4th dimension added
function upsample_pl4d(pl,dist)
local header = {}
local body = {}
-- todo: maybe use http post
clib:setopt(curl.OPT_URL,'http://localhost/cgi-bin/elpro.fcgi?'..params(pl,dist))
clib:setopt(curl.OPT_HEADERFUNCTION,function(s,len) table.insert(header,s) return len,nil end)
clib:setopt(curl.OPT_WRITEFUNCTION,function(s,len) table.insert(body,s) return len,nil end)
clib:perform()
local r=json.decode(table.concat(body))
assert(r['status']=='OK')
return r['results']
end

function last(t)
return t[table.maxn(t)]
end

-- input: 4d polyline
-- output: distance/elevation deltas
function dz(pl)
local r={}
for i=1,table.maxn(pl)-1 do
r[i]={pl[i+1][4]-pl[i][4],pl[i+1][3]-pl[i][3]}
end
return r
end

-- simple speed function depending on gradient
-- input: gradient
-- output: speed
function speed(g)
if g>0 then
return math.max(3,15-100*g)
else
return math.min(50,15-50*g)
end
end

-- input: pl
-- output: average speed
function avg_speed_and_length(pl)
local pl4d=upsample_pl4d(pl,50)
local l=last(pl4d)[4]
local dzs=dz(pl4d)
local speeds=map(speed, map(function(x) return x[2]/x[1] end, dzs))
local time=0
for i=1,table.maxn(speeds) do
time=time+dzs[i][1]/speeds[i]
end
return {l/time,l}
end

-- calculate segment weight
function segment_function(lat1, lon1, lat2, lon2, speed, distance)
-- todo: what about input speed?!
local r=avg_speed_and_length({{lat1/1e5,lon1/1e5},{lat2/1e5,lon2/1e5}})
local as=r[1]
local length=r[2]
-- todo: compare length to distance
return length*10/(as/3.6)
end

0 comments on commit aeb7927

Please sign in to comment.