diff options
author | Alexander Sulfrian <alexander@sulfrian.net> | 2011-01-29 14:00:40 +0100 |
---|---|---|
committer | Alexander Sulfrian <alexander@sulfrian.net> | 2011-01-29 14:00:40 +0100 |
commit | d857e652d28ab6988b60d3d72e3b4432d0125eaf (patch) | |
tree | 5ad69e6d738102bcd7fdd19034ea5efed8c36b84 | |
parent | a9a2daeebf8ef351b3efe74549026ce7619873ff (diff) | |
parent | db5acf7cda7855bb22660f993cc0c25dd27bf631 (diff) | |
download | osm-xapi-d857e652d28ab6988b60d3d72e3b4432d0125eaf.tar.gz osm-xapi-d857e652d28ab6988b60d3d72e3b4432d0125eaf.tar.xz osm-xapi-d857e652d28ab6988b60d3d72e3b4432d0125eaf.zip |
Merge remote branch 'upstream/master'
Conflicts:
src/nodejs/main.js
-rw-r--r-- | src/nodejs/alternative/xapi-peg-grammar.peg | 48 | ||||
-rw-r--r-- | src/nodejs/alternative/xapi-peg-parser.js | 151 | ||||
-rw-r--r-- | src/nodejs/main.js | 240 | ||||
-rw-r--r-- | src/nodejs/parse.js | 155 | ||||
-rw-r--r-- | src/nodejs/tests/pathparsing.js | 8 | ||||
-rw-r--r-- | src/nodejs/tests/urlToResObj.js | 63 | ||||
-rw-r--r-- | src/nodejs/xmlGenerator.js | 29 |
7 files changed, 524 insertions, 170 deletions
diff --git a/src/nodejs/alternative/xapi-peg-grammar.peg b/src/nodejs/alternative/xapi-peg-grammar.peg new file mode 100644 index 0000000..d9f5547 --- /dev/null +++ b/src/nodejs/alternative/xapi-peg-grammar.peg @@ -0,0 +1,48 @@ +Expr ← Path Type XPath? +Path ← "/" +Type ← WildCard / "node" / "way" / "relation" +XPath ← Bbox (Tag Child?)? / Bbox Child Tag? / Tag (Bbox Child?)? / Tag Child Bbox? / Child (Tag Bbox?)? / Child Bbox Tag? +Bbox ← LeftBracket BboxPredicate RightBracket +Tag ← LeftBracket TagPredicate RightBracket +Child ← LeftBracket ChildPredicate RightBracket + +BboxPredicate ← [bB] [bB] [oO] [xX] Equals Left Komma Bottom Komma Right Komma Top +Left ← Coordinate +Bottom ← Coordinate +Right ← Coordinate +Top ← Coordinate +Coordinate ← Sign? Double / Sign? Integer + +TagPredicate ← Keys Equals Vals + +Keys ← Key (Pipe Key)* +Key ← Chars +Vals ← WildCard / Val +Val ← Chars Pipe Keys / Chars + +Chars ← Char (Char)* +SpecialChar ← Escape Special +Special ← Equals / LeftBracket / RightBracket / LeftParent / RightParent / Pipe / Backslash +Space ← [ U+0020 ] +Equals ← [ U+003D ] +Escape ← [ U+005C ] +LeftBracket ← [ U+005B ] +RightBracket ← [ U+005D ] +LeftParent ← [ U+0028 ] +RightParent ← [ U+0029 ] +Backslash ← [ U+005C ] +Pipe ← [ U+007C ] +Char ← SpecialChar / [U+0021-U+0027] / [U+002B-U+003C] / [U+003E-U+005A] / [U+005C] / [U+005E-U+007B] / [U+007D-U+FFFF] + +ChildPredicate ← "nd" / "not(nd)" / "tag" / "not(tag)" / "not(tag)" / "way" / "not(way)" / "node" / "not(node)" / "relation" / "not(relation)" + +Integer ← "0" / Sign? [1-9] [0-9]* +Double ← Integer "." [0-9]* +Sign ← "+" / "-" +Empty ← "" + +Dot ← "." +Komma ← "," +WildCard ← "*" +CR ← [U+0013] +LF ← [U+000A]
\ No newline at end of file diff --git a/src/nodejs/alternative/xapi-peg-parser.js b/src/nodejs/alternative/xapi-peg-parser.js new file mode 100644 index 0000000..45345c5 --- /dev/null +++ b/src/nodejs/alternative/xapi-peg-parser.js @@ -0,0 +1,151 @@ +function parseToXML(string){ + var res = Expr(string); + return (res[0] ? f(res[1],0,string) : 'parse error') + function f(n,p,s){ + var ret,i,l + if (n[0] == -1) + return string.substring(p,p+n[1]) + ret = '<' + Expr.names[n[0]] + ' raw="' + string.substring(p,p+n[1]) + '">'; + for(i=0 , l=n[2].length ; i<l ; i++) + { + ret += '\n' + f(n[2][i],p,s) + p += n[2][i][1] + } + ret += '\n' + '<\\' + Expr.names[n[0]]+'>' + return ret.replace(/\n/g,'\n ') + } +} + +function Expr(str){ + var tbl=[],pos=0,l=str.length+1;while(l--)tbl.push([]);l=str.length; + function Expr(a){var x,p=pos,c;if(x=tbl[p][0]){pos=x[1];a.push([p,0]);return 1}if(x==false){return 0}c=[];return fin(c,p,0,_Expr(c),a)} + function Path(a){var x,p=pos,c;if(x=tbl[p][1]){pos=x[1];a.push([p,1]);return 1}if(x==false){return 0}c=[];return fin(c,p,1,_Path(c),a)} + function Type(a){var x,p=pos,c;if(x=tbl[p][2]){pos=x[1];a.push([p,2]);return 1}if(x==false){return 0}c=[];return fin(c,p,2,_Type(c),a)} + function XPath(a){var x,p=pos,c;if(x=tbl[p][3]){pos=x[1];a.push([p,3]);return 1}if(x==false){return 0}c=[];return fin(c,p,3,_XPath(c),a)} + function Bbox(a){var x,p=pos,c;if(x=tbl[p][4]){pos=x[1];a.push([p,4]);return 1}if(x==false){return 0}c=[];return fin(c,p,4,_Bbox(c),a)} + function Tag(a){var x,p=pos,c;if(x=tbl[p][5]){pos=x[1];a.push([p,5]);return 1}if(x==false){return 0}c=[];return fin(c,p,5,_Tag(c),a)} + function Child(a){var x,p=pos,c;if(x=tbl[p][6]){pos=x[1];a.push([p,6]);return 1}if(x==false){return 0}c=[];return fin(c,p,6,_Child(c),a)} + function BboxPredicate(a){var x,p=pos,c;if(x=tbl[p][7]){pos=x[1];a.push([p,7]);return 1}if(x==false){return 0}c=[];return fin(c,p,7,_BboxPredicate(c),a)} + function Left(a){var x,p=pos,c;if(x=tbl[p][8]){pos=x[1];a.push([p,8]);return 1}if(x==false){return 0}c=[];return fin(c,p,8,_Left(c),a)} + function Bottom(a){var x,p=pos,c;if(x=tbl[p][9]){pos=x[1];a.push([p,9]);return 1}if(x==false){return 0}c=[];return fin(c,p,9,_Bottom(c),a)} + function Right(a){var x,p=pos,c;if(x=tbl[p][10]){pos=x[1];a.push([p,10]);return 1}if(x==false){return 0}c=[];return fin(c,p,10,_Right(c),a)} + function Top(a){var x,p=pos,c;if(x=tbl[p][11]){pos=x[1];a.push([p,11]);return 1}if(x==false){return 0}c=[];return fin(c,p,11,_Top(c),a)} + function Coordinate(a){var x,p=pos,c;if(x=tbl[p][12]){pos=x[1];a.push([p,12]);return 1}if(x==false){return 0}c=[];return fin(c,p,12,_Coordinate(c),a)} + function TagPredicate(a){var x,p=pos,c;if(x=tbl[p][13]){pos=x[1];a.push([p,13]);return 1}if(x==false){return 0}c=[];return fin(c,p,13,_TagPredicate(c),a)} + function Keys(a){var x,p=pos,c;if(x=tbl[p][14]){pos=x[1];a.push([p,14]);return 1}if(x==false){return 0}c=[];return fin(c,p,14,_Keys(c),a)} + function Key(a){var x,p=pos,c;if(x=tbl[p][15]){pos=x[1];a.push([p,15]);return 1}if(x==false){return 0}c=[];return fin(c,p,15,_Key(c),a)} + function Vals(a){var x,p=pos,c;if(x=tbl[p][16]){pos=x[1];a.push([p,16]);return 1}if(x==false){return 0}c=[];return fin(c,p,16,_Vals(c),a)} + function Val(a){var x,p=pos,c;if(x=tbl[p][17]){pos=x[1];a.push([p,17]);return 1}if(x==false){return 0}c=[];return fin(c,p,17,_Val(c),a)} + function Chars(a){var x,p=pos,c;if(x=tbl[p][18]){pos=x[1];a.push([p,18]);return 1}if(x==false){return 0}c=[];return fin(c,p,18,_Chars(c),a)} + function SpecialChar(a){var x,p=pos,c;if(x=tbl[p][19]){pos=x[1];a.push([p,19]);return 1}if(x==false){return 0}c=[];return fin(c,p,19,_SpecialChar(c),a)} + function Special(a){var x,p=pos,c;if(x=tbl[p][20]){pos=x[1];a.push([p,20]);return 1}if(x==false){return 0}c=[];return fin(c,p,20,_Special(c),a)} + function Space(a){var x,p=pos,c;if(x=tbl[p][21]){pos=x[1];a.push([p,21]);return 1}if(x==false){return 0}c=[];return fin(c,p,21,_Space(c),a)} + function Equals(a){var x,p=pos,c;if(x=tbl[p][22]){pos=x[1];a.push([p,22]);return 1}if(x==false){return 0}c=[];return fin(c,p,22,_Equals(c),a)} + function Escape(a){var x,p=pos,c;if(x=tbl[p][23]){pos=x[1];a.push([p,23]);return 1}if(x==false){return 0}c=[];return fin(c,p,23,_Escape(c),a)} + function LeftBracket(a){var x,p=pos,c;if(x=tbl[p][24]){pos=x[1];a.push([p,24]);return 1}if(x==false){return 0}c=[];return fin(c,p,24,_LeftBracket(c),a)} + function RightBracket(a){var x,p=pos,c;if(x=tbl[p][25]){pos=x[1];a.push([p,25]);return 1}if(x==false){return 0}c=[];return fin(c,p,25,_RightBracket(c),a)} + function LeftParent(a){var x,p=pos,c;if(x=tbl[p][26]){pos=x[1];a.push([p,26]);return 1}if(x==false){return 0}c=[];return fin(c,p,26,_LeftParent(c),a)} + function RightParent(a){var x,p=pos,c;if(x=tbl[p][27]){pos=x[1];a.push([p,27]);return 1}if(x==false){return 0}c=[];return fin(c,p,27,_RightParent(c),a)} + function Backslash(a){var x,p=pos,c;if(x=tbl[p][28]){pos=x[1];a.push([p,28]);return 1}if(x==false){return 0}c=[];return fin(c,p,28,_Backslash(c),a)} + function Pipe(a){var x,p=pos,c;if(x=tbl[p][29]){pos=x[1];a.push([p,29]);return 1}if(x==false){return 0}c=[];return fin(c,p,29,_Pipe(c),a)} + function Char(a){var x,p=pos,c;if(x=tbl[p][30]){pos=x[1];a.push([p,30]);return 1}if(x==false){return 0}c=[];return fin(c,p,30,_Char(c),a)} + function ChildPredicate(a){var x,p=pos,c;if(x=tbl[p][31]){pos=x[1];a.push([p,31]);return 1}if(x==false){return 0}c=[];return fin(c,p,31,_ChildPredicate(c),a)} + function Integer(a){var x,p=pos,c;if(x=tbl[p][32]){pos=x[1];a.push([p,32]);return 1}if(x==false){return 0}c=[];return fin(c,p,32,_Integer(c),a)} + function Double(a){var x,p=pos,c;if(x=tbl[p][33]){pos=x[1];a.push([p,33]);return 1}if(x==false){return 0}c=[];return fin(c,p,33,_Double(c),a)} + function Sign(a){var x,p=pos,c;if(x=tbl[p][34]){pos=x[1];a.push([p,34]);return 1}if(x==false){return 0}c=[];return fin(c,p,34,_Sign(c),a)} + function Empty(a){var x,p=pos,c;if(x=tbl[p][35]){pos=x[1];a.push([p,35]);return 1}if(x==false){return 0}c=[];return fin(c,p,35,_Empty(c),a)} + function Dot(a){var x,p=pos,c;if(x=tbl[p][36]){pos=x[1];a.push([p,36]);return 1}if(x==false){return 0}c=[];return fin(c,p,36,_Dot(c),a)} + function Komma(a){var x,p=pos,c;if(x=tbl[p][37]){pos=x[1];a.push([p,37]);return 1}if(x==false){return 0}c=[];return fin(c,p,37,_Komma(c),a)} + function WildCard(a){var x,p=pos,c;if(x=tbl[p][38]){pos=x[1];a.push([p,38]);return 1}if(x==false){return 0}c=[];return fin(c,p,38,_WildCard(c),a)} + function CR(a){var x,p=pos,c;if(x=tbl[p][39]){pos=x[1];a.push([p,39]);return 1}if(x==false){return 0}c=[];return fin(c,p,39,_CR(c),a)} + function LF(a){var x,p=pos,c;if(x=tbl[p][40]){pos=x[1];a.push([p,40]);return 1}if(x==false){return 0}c=[];return fin(c,p,40,_LF(c),a)} + var _Expr=q(Path,Type,r(0,1,XPath)) + var _Path=sl_0 + var _Type=o(WildCard,sl_1,sl_2,sl_3) + var _XPath=o(q(Bbox,r(0,1,q(Tag,r(0,1,Child)))),q(Bbox,Child,r(0,1,Tag)),q(Tag,r(0,1,q(Bbox,r(0,1,Child)))),q(Tag,Child,r(0,1,Bbox)),q(Child,r(0,1,q(Tag,r(0,1,Bbox)))),q(Child,Bbox,r(0,1,Tag))) + var _Bbox=q(LeftBracket,BboxPredicate,RightBracket) + var _Tag=q(LeftBracket,TagPredicate,RightBracket) + var _Child=q(LeftBracket,ChildPredicate,RightBracket) + var _BboxPredicate=q(cs_0,cs_0,cs_1,cs_2,Equals,Left,Komma,Bottom,Komma,Right,Komma,Top) + var _Left=Coordinate + var _Bottom=Coordinate + var _Right=Coordinate + var _Top=Coordinate + var _Coordinate=o(q(r(0,1,Sign),Double),q(r(0,1,Sign),Integer)) + var _TagPredicate=q(Keys,Equals,Vals) + var _Keys=q(Key,r(0,0,q(Pipe,Key))) + var _Key=Chars + var _Vals=o(WildCard,Val) + var _Val=o(q(Chars,Pipe,Keys),Chars) + var _Chars=q(Char,r(0,0,Char)) + var _SpecialChar=q(Escape,Special) + var _Special=o(Equals,LeftBracket,RightBracket,LeftParent,RightParent,Pipe,Backslash) + var _Space=cs_3 + var _Equals=cs_4 + var _Escape=cs_5 + var _LeftBracket=cs_6 + var _RightBracket=cs_7 + var _LeftParent=cs_8 + var _RightParent=cs_9 + var _Backslash=cs_5 + var _Pipe=cs_10 + var _Char=o(SpecialChar,cs_11,cs_12,cs_13,cs_5,cs_14,cs_15) + var _ChildPredicate=o(sl_4,sl_5,sl_6,sl_7,sl_7,sl_2,sl_8,sl_1,sl_9,sl_3,sl_10) + var _Integer=o(sl_11,q(r(0,1,Sign),cs_16,r(0,0,cs_17))) + var _Double=q(Integer,sl_12,r(0,0,cs_17)) + var _Sign=o(sl_13,sl_14) + var _Empty=e + var _Dot=sl_12 + var _Komma=sl_15 + var _WildCard=sl_16 + var _CR=cs_18 + var _LF=cs_19 + function cs_0(){var c,x;if(pos==l)return false;c=g(pos);x=c<67?c<66?0:1:c<98?0:c<99?1:0;if(x){pos++;return true}return false} + function cs_1(){var c,x;if(pos==l)return false;c=g(pos);x=c<80?c<79?0:1:c<111?0:c<112?1:0;if(x){pos++;return true}return false} + function cs_2(){var c,x;if(pos==l)return false;c=g(pos);x=c<89?c<88?0:1:c<120?0:c<121?1:0;if(x){pos++;return true}return false} + function cs_3(){var c,x;if(pos==l)return false;c=g(pos);x=c<32?0:c<33?1:0;if(x){pos++;return true}return false} + function cs_4(){var c,x;if(pos==l)return false;c=g(pos);x=c<61?0:c<62?1:0;if(x){pos++;return true}return false} + function cs_5(){var c,x;if(pos==l)return false;c=g(pos);x=c<92?0:c<93?1:0;if(x){pos++;return true}return false} + function cs_6(){var c,x;if(pos==l)return false;c=g(pos);x=c<91?0:c<92?1:0;if(x){pos++;return true}return false} + function cs_7(){var c,x;if(pos==l)return false;c=g(pos);x=c<93?0:c<94?1:0;if(x){pos++;return true}return false} + function cs_8(){var c,x;if(pos==l)return false;c=g(pos);x=c<40?0:c<41?1:0;if(x){pos++;return true}return false} + function cs_9(){var c,x;if(pos==l)return false;c=g(pos);x=c<41?0:c<42?1:0;if(x){pos++;return true}return false} + function cs_10(){var c,x;if(pos==l)return false;c=g(pos);x=c<124?0:c<125?1:0;if(x){pos++;return true}return false} + function cs_11(){var c,x;if(pos==l)return false;c=g(pos);x=c<33?0:c<40?1:0;if(x){pos++;return true}return false} + function cs_12(){var c,x;if(pos==l)return false;c=g(pos);x=c<43?0:c<61?1:0;if(x){pos++;return true}return false} + function cs_13(){var c,x;if(pos==l)return false;c=g(pos);x=c<62?0:c<91?1:0;if(x){pos++;return true}return false} + function cs_14(){var c,x;if(pos==l)return false;c=g(pos);x=c<94?0:c<124?1:0;if(x){pos++;return true}return false} + function cs_15(){var c,x;if(pos==l)return false;c=g(pos);x=c<125?0:c<65536?1:0;if(x){pos++;return true}return false} + function cs_16(){var c,x;if(pos==l)return false;c=g(pos);x=c<49?0:c<58?1:0;if(x){pos++;return true}return false} + function cs_17(){var c,x;if(pos==l)return false;c=g(pos);x=c<48?0:c<58?1:0;if(x){pos++;return true}return false} + function cs_18(){var c,x;if(pos==l)return false;c=g(pos);x=c<19?0:c<20?1:0;if(x){pos++;return true}return false} + function cs_19(){var c,x;if(pos==l)return false;c=g(pos);x=c<10?0:c<11?1:0;if(x){pos++;return true}return false} + function sl_0(){var p=pos;if(str.charCodeAt(p)==47){pos+=1;return true}return false} + function sl_1(){var p=pos;if(str.charCodeAt(p++)==110&&str.charCodeAt(p++)==111&&str.charCodeAt(p++)==100&&str.charCodeAt(p)==101){pos+=4;return true}return false} + function sl_2(){var p=pos;if(str.charCodeAt(p++)==119&&str.charCodeAt(p++)==97&&str.charCodeAt(p)==121){pos+=3;return true}return false} + function sl_3(){var p=pos;if(str.charCodeAt(p++)==114&&str.charCodeAt(p++)==101&&str.charCodeAt(p++)==108&&str.charCodeAt(p++)==97&&str.charCodeAt(p++)==116&&str.charCodeAt(p++)==105&&str.charCodeAt(p++)==111&&str.charCodeAt(p)==110){pos+=8;return true}return false} + function sl_4(){var p=pos;if(str.charCodeAt(p++)==110&&str.charCodeAt(p)==100){pos+=2;return true}return false} + function sl_5(){var p=pos;if(str.charCodeAt(p++)==110&&str.charCodeAt(p++)==111&&str.charCodeAt(p++)==116&&str.charCodeAt(p++)==40&&str.charCodeAt(p++)==110&&str.charCodeAt(p++)==100&&str.charCodeAt(p)==41){pos+=7;return true}return false} + function sl_6(){var p=pos;if(str.charCodeAt(p++)==116&&str.charCodeAt(p++)==97&&str.charCodeAt(p)==103){pos+=3;return true}return false} + function sl_7(){var p=pos;if(str.charCodeAt(p++)==110&&str.charCodeAt(p++)==111&&str.charCodeAt(p++)==116&&str.charCodeAt(p++)==40&&str.charCodeAt(p++)==116&&str.charCodeAt(p++)==97&&str.charCodeAt(p++)==103&&str.charCodeAt(p)==41){pos+=8;return true}return false} + function sl_8(){var p=pos;if(str.charCodeAt(p++)==110&&str.charCodeAt(p++)==111&&str.charCodeAt(p++)==116&&str.charCodeAt(p++)==40&&str.charCodeAt(p++)==119&&str.charCodeAt(p++)==97&&str.charCodeAt(p++)==121&&str.charCodeAt(p)==41){pos+=8;return true}return false} + function sl_9(){var x=str.slice(pos,pos+9);if(x=="not(node)"){pos+=9;return true}return false} + function sl_10(){var x=str.slice(pos,pos+13);if(x=="not(relation)"){pos+=13;return true}return false} + function sl_11(){var p=pos;if(str.charCodeAt(p)==48){pos+=1;return true}return false} + function sl_12(){var p=pos;if(str.charCodeAt(p)==46){pos+=1;return true}return false} + function sl_13(){var p=pos;if(str.charCodeAt(p)==43){pos+=1;return true}return false} + function sl_14(){var p=pos;if(str.charCodeAt(p)==45){pos+=1;return true}return false} + function sl_15(){var p=pos;if(str.charCodeAt(p)==44){pos+=1;return true}return false} + function sl_16(){var p=pos;if(str.charCodeAt(p)==42){pos+=1;return true}return false} + function fin(c,p,x,r,a){if(r)a.push([p,x]);tbl[p][x]=r?[true,pos,c]:false;return r} + function e(){return true} + function o(){var args=arguments;return function(c){var i,l;for(i=0,l=args.length;i<l;i++)if(args[i](c))return true;return false}} + function q(){var args=arguments;return function(c){var i,l,cp=pos,cl=c.length;for(i=0,l=args.length;i<l;i++)if(!args[i](c)){pos=cp;t(c,cl);return false}return true}} + function r(m,n,f){return function(c){var i=0,cp=pos,cl=c.length;while(i<m){i++;if(!f(c)){pos=cp;t(c,cl);return false}}cl=c.length;while(i++<n||n==0)if(!f(c))return true;return true}} + function n(f){return function(){var p=pos,x=f([]);pos=p;return !x}} + function p(f){return function(){var p=pos,x=f([]);pos=p;return x}} + function t(a,n){if(a.length>n)a.splice(n)} + function g(p){return str.charCodeAt(p)} + function b(p,n){var x=tbl[p][n],c=[],a=[n,x[1]-p,c],y=x[2],i=0,l=y.length,z;for(;i<l;i++){z=y[i];if(z[0]>p)c.push([-1,z[0]-p]);c.push(b(z[0],z[1]));p=tbl[z[0]][z[1]][1]}if(p<x[1]&&c.count)c.push([-1,x[1]-p]);return a} + return Expr([])&&pos==l?[true,b(0,0)]:[false,pos,tbl]} +Expr.names=['Expr','Path','Type','XPath','Bbox','Tag','Child','BboxPredicate','Left','Bottom','Right','Top','Coordinate','TagPredicate','Keys','Key','Vals','Val','Chars','SpecialChar','Special','Space','Equals','Escape','LeftBracket','RightBracket','LeftParent','RightParent','Backslash','Pipe','Char','ChildPredicate','Integer','Double','Sign','Empty','Dot','Komma','WildCard','CR','LF'];
\ No newline at end of file diff --git a/src/nodejs/main.js b/src/nodejs/main.js index a7ff07b..80bd051 100644 --- a/src/nodejs/main.js +++ b/src/nodejs/main.js @@ -7,6 +7,7 @@ var opts = require('opts'); var osmRes = require('./response'); var log4js = require('log4js')(); var log = log4js.getLogger('global'); +var parser = require('./parse'); var config; // #################### MAY be put to different module later @@ -65,11 +66,11 @@ function rowToWay(row){ 'changeset' : row.changeset_id }; if(row.tags != '{}') { - node.tags = []; + way.tags = []; // FIXME: something doesnt work at all temp = row.tags.replace("{","").replace("}","").split(","); for(var x=0;x<temp.length;x=x+2){ - node.tags.push({ + way.tags.push({ 'k' : temp[x], 'v' : temp[x+1] }); @@ -80,120 +81,107 @@ function rowToWay(row){ // #################### MAY be put to different module later +var options = [ + { short : 'c', + long : 'config', + description : 'Select configuration file', + value : true + } +]; -// #################### my little clutch replacments - - -var urlToXpathObj = function urlToXpathObj(url){ - - // FIXME: more validaiton - // filter stars in keys - // filter no enough arguments +// +// { +// object = node/way/relation/* , +// bbox = { left : 1.0 , right : 1.0 , top : 1.0, bottom : 1.0 } +// tag = { key : [ ], value [ ] } +// } + + +function buildMainQuery(reqJso){ + + var id = 1; + var replacements = Array(); + + var selectMap = { + 'node' : 'id,user_id,tstamp,version,changeset_id,hstore_to_array(tags) as tags, ' + + 'X(geom) as lat, Y(geom) as lon', + 'way' : 'id,tstamp,version,changeset_id,nodes,user_id,hstore_to_array(tags) as tags ', + 'relation' : '' //FIXME: plz + } + + // FIXME: help me i am not side effect free + function buildTagsQuery(map){ + + tagQueries = new Array(); + + for(tagkey in map){ + tagQueries.push("tags @> hstore($" + id++ + ",$" + id++ + ")"); + replacements.push(tagkey); + replacements.push(map[tagkey]); + } - var parseKeyList = function(string){ - result = /(.+)(:?\|(.+))/.exec(string); - result.shift(); - return result; + return tagQueries.join(" OR \n"); } - var parseBboxList = function(string){ - - result = /(.+)(:?,(.+)){3}/.exec(string); - - if(result.length != 4){ - throw "error"; + // FIXME: help me i am not side effect free + function buildBbox(object,bbox){ + + var colName = { + node : 'geom', + way : 'linestring', + relation : '' // FIXME: whats my name } - result.shift(); + bboxQueryStr = colName[object] + ' && st_setsrid(st_makebox2d( ' + + ' st_setsrid(st_makepoint($' + id++ + ', $' + id++ + '), 4326), ' + + ' st_setsrid(st_makepoint($' + id++ + ', $' + id++ + '), 4326) ' + + ' ), 4326) '; + + for( direction in bbox ) { + replacements.push(bbox[direction]); + } - return { - 'left' : result[0], - 'bottom' : result[1], - 'right' : result[2], - 'top' : result[3] - }; + return bboxQueryStr; } - var xp = {}; - - result = /\/(*|node|way|relation)(:?\[(.*)=(.*)\])*/.exec(url); - - xp.object=result[1]; - - for(i=2;i<=result.length();i++){ - if(result[i]==="bbox"){ - xp.bbox = parseBboxValues(result[i+1]); - } else { - xp.tag ={}; - xp.tag.keys = parseKeyList(result[i]); - xp.tag.values = parseKeyList(result[i+1]); + function explodeTags(keys,values){ + var map = {}; + for(key in keys) { + for(value in values) { + map[keys[key]]=values[value]; // FIXME: das ist scheiße + } } - i++; + return map; } -} - - - - - - - -// ################## end my little clutch replacments - - - + + query = "SELECT " + selectMap[reqJso.object] + " FROM " + reqJso.object + "s"; + + whereClauses = Array(); + if(reqJso.bbox != undefined){ + whereClauses.push(buildBbox(reqJso.object,reqJso.bbox)); + } + + // FIXME: rename tag to tags key to keys value to values + if(reqJso.tag != undefined){ + tags = explodeTags(reqJso.tag.key,reqJso.tag.value); + whereClauses.push(buildTagsQuery(tags)); + } + if(whereClauses.length > 0) { + query += ' WHERE (' + whereClauses.join(' AND ') + ')'; + } -var options = [ - { short : 'c', - long : 'config', - description : 'Select configuration file', - value : true - } -]; + query += ';' -function createWayBboxQuery(key, value, left, bottom, right, top) { return { - text: 'SELECT id,tstamp,version,changeset_id,nodes,user_id,hstore_to_array(tags) as tags ' + - 'FROM ways ' + - 'WHERE ( ' + - ' tags @> hstore($1, $2) AND ' + - ' linestring && st_setsrid(st_makebox2d( ' + - ' st_setsrid(st_makepoint($3, $4), 4326), ' + - ' st_setsrid(st_makepoint($5, $6), 4326) ' + - ' ), 4326) ' + - ')', - values: [key, value, left, bottom, right, top], - name: 'way bbox query' - }; + text:query, + values:replacements, + name: query + }; } -function createNodeBboxQuery(key, value, left, bottom, right, top) { - return { - text: 'SELECT id,user_id,tstamp,version,changeset_id,hstore_to_array(tags) as tags, X(geom) as lat, Y(geom) as lon ' + - 'FROM nodes ' + - 'WHERE ( ' + - ' tags @> hstore($1, $2) AND ' + - ' geom && st_setsrid(st_makebox2d( ' + - ' st_setsrid(st_makepoint($3, $4), 4326), ' + - ' st_setsrid(st_makepoint($5, $6), 4326) ' + - ' ), 4326) ' + - ')', - values: [key, value, left, bottom, right, top], - name: 'node bbox query' - }; -} -function createNodesForWayQuery(nodes) { - return { - text: 'SELECT id,tstamp,version,changeset_id,hstore_to_array(tags) as tags, X(geom) as lat, Y(geom) as lon ' + - 'FROM nodes ' + - 'WHERE (id = ANY($1))', - values: [nodes], - name: 'nodes for way' - }; -} function dbConnect(res, callback) { pg.connect(config.connectionString, function(err, client) { @@ -251,7 +239,7 @@ function wayBboxHandler(req, res, key, value, left, bottom, right, top) { dbConnect(res, function(client) { var count = 0; var success = false; - //console.log(createWayBboxQuery(key, value, left, bottom, right, top)); + console.log(createWayBboxQuery(key, value, left, bottom, right, top)); var query = client.query(createWayBboxQuery(key, value, left, bottom, right, top)); query.on('error', function(err) { @@ -284,26 +272,46 @@ function wayBboxHandler(req, res, key, value, left, bottom, right, top) { }); } -function relationWorldHandler(req, res, key, value) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end(' key:' +key +' value:'+value+'!\n'); -} -function relationBboxHandler(req, res, key, value, left, bottom, right, top) { +function myFunction(req,res){ -} + res.writeHead(200); + + var reqObj = parser.urlToXpathObj(req.url); + + var queryDict = buildMainQuery(reqObj); + + var resXml = osmRes.mkXmlRes(res); + -myRoutes = clutch.route404([ - //['GET /api/(\\w+)(\\[bbox=(\\d,\\d,\\d,\\d)\\])*\\[(\\w+)=(\\w+)\\]$', helloSomeone], - ['GET /api/node\\[(\\w+)=(\\w+)\\]$',nodeWorldHandler], - //['GET /api/node\\[(\\w+)=(\\w+)\\]\\[bbox=(\\d+(\\.\\d+)?),(\\d+),(\\d+),(\\d+)\\]$',nodeBboxHandler], - ['GET /api/node\\[(\\w+)=(\\w+)\\]\\[bbox=(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?)\\]$',nodeBboxHandler], - //['GET /api/node\\[(\\w+)=(\\w+)\\]\\[bbox=(\\d+\\.\\d+),(\\d+),(\\d+),(\\d+)\\]$',nodeBboxHandler], - ['GET /api/way\\[(\\w+)=(\\w+)\\]$',wayWorldHandler], - ['GET /api/way\\[(\\w+)=(\\w+)\\]\\[bbox=(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?),(\\d+(?:\\.\\d+)?)\\]$',wayBboxHandler], - ['GET /api/relation\\[(\\w+)=(\\w+)\\]$',relationWorldHandler] - //['GET /api/relation\\[(\\w+)=(\\w+)\\](\\[bbox=(\\d),(\\d),(\\d),(\\d)\\])$',relationBboxHandler], -]); + console.log(JSON.stringify(queryDict)); + console.log("??????????????????????????????"); + console.log(JSON.stringify(reqObj)); + dbConnect(resXml, function(client) { + var success = false; + var query = client.query(queryDict); + + query.on('error', function(err) { + res.endWith500(); + }); + + query.on('end', function() { + console.log(" EEEND "); + res.atEnd(); + }); + + query.on('row', function(row) { + //console.log(JSON.stringify(row)); + if(reqObj.object == "node") { + var pojo = rowToNode(row); + res.putNode(pojo); + } + else if(reqObj.object == "way") { + var pojo = rowToWay(row); + res.putWay(pojo);} + }); + }); +} function getConfig(configPath, callback) { if( configPath[0] != '/'){ @@ -323,7 +331,7 @@ function init(newConfig) { log.setLevel(config.logLevel); log.info("server starting..."); log.info("loaded config from " + configPath); - http.createServer(myRoutes).listen(config.port, config.host); + http.createServer(myFunction).listen(config.port, config.host); log.info("Started server at " + config.host + ":" + config.port ); } diff --git a/src/nodejs/parse.js b/src/nodejs/parse.js index 0338954..321823b 100644 --- a/src/nodejs/parse.js +++ b/src/nodejs/parse.js @@ -1,48 +1,131 @@ -exports.urlToXpathObj = function urlToXpathObj(url){ - // FIXMEresult.shift(): more validaiton - // filter stars in keys - // filter no enough arguments - var parseKeyList = function(string){ - result = /(.+)(:?\|(.+))/.exec(string); - result.shift(); - return result; - } +var parser = function(){ - var parseBboxList = function(string){ + var offset =0; + var expr =""; - result = /(.+)(:?,(.+)){3}/.exec(string); + var keys = []; + var values = []; + var bbox= {}; + var object = ""; - if(result.length != 4){ - throw "error"; - } + var check = function(char){ + if (expr.charAt(offset) != char) { + throw "Unexpected char " + expr[offset] + " at " + offset + " expected: " + char; + } + offset ++; + } + + var parsePredicate = function(){ + check('['); + parseInnerPredicate(); + check(']'); + } - result.shift(); + var parseInnerPredicate = function(){ + tmpKeys=[]; + parseKeyValue(tmpKeys,'='); + check('='); + if(tmpKeys.length==1 && tmpKeys[0] == "bbox"){ + parseBboxValues(); + } else { + keys = tmpKeys; + parseKeyValue(values,']'); + } + } - return { - 'left' : result[0], - 'bottom' : result[1], - 'right' : result[2], - 'top' : result[3] - } - } - - var xp = {}; + var parseBboxValues = function(){ + bbox.left = parseBboxFloat(); + check(','); + bbox.bottom = parseBboxFloat(); + check(','); + bbox.right = parseBboxFloat(); + check(','); + bbox.top = parseBboxFloat(); + } - result = /\/(*|node|way|relation)(:?\[(.*)=(.*)\])*/.exec(url); + var parseBboxFloat = function(){ + var floatStr = ""; + while(expr[offset]!=',' && expr[offset]!=']' && offset < expr.length){ + floatStr += expr[offset]; + offset ++; + } + return parseFloat(floatStr); + } - xp.object=result[1]; + var parseKeyValue = function(list,delim){ + var word = ""; + while(expr[offset]!=delim && offset < expr.length){ + if(expr[offset]=='|'){ + list.push(word); + word=""; + offset ++; + continue; + } + // jump escaped chars + if(expr[offset]=='\\'){ + word += expr[offset]; + offset ++; + } + word += expr[offset]; + offset ++; + } + list.push(word); - for(i=2;i<=result.length;i++){ - if(result[i]==="bbox"){ - xp.bbox = parseBboxValues(result[i+1]); - } else { - xp.tag ={}; - xp.tag.keys = parseKeyList(result[i]); - xp.tag.values = parseKeyList(result[i+1]); - } - i++; - } + } + + this.parse = function(exprLocal){ + expr = exprLocal; + offset = 0; + object = ""; + + + + check('/'); + + for(;expr[offset]!='[' && offset<expr.length;offset++){ + if(expr[offset] == '/' && offset == expr.length-1){ + offset ++; + break; + } + object += expr[offset]; + } + + if (object != "*" && object != "way" && object != "node" && object != "relation"){ + throw "invalid identifier: " + object; + } + + + for(var i=0; i<3 && offset < expr.length;i++) { + parsePredicate(); + } + if (offset < expr.length){ + + throw "string longer than excepected"; + } + + var result = { + object : object + }; + + if(bbox.left != undefined){ + result.bbox = bbox; + } + + if(keys.length > 0){ + + result.tag = { + key : keys, + value : values + } + } + return result; + } } + +exports.urlToXpathObj = function urlToXpathObj(url){ + var parse = new parser(); + return parse.parse(url); +} diff --git a/src/nodejs/tests/pathparsing.js b/src/nodejs/tests/pathparsing.js index e1a20f5..ebd5baf 100644 --- a/src/nodejs/tests/pathparsing.js +++ b/src/nodejs/tests/pathparsing.js @@ -54,7 +54,7 @@ module.exports = test.ok(true); var simpleRelationStringTrail = "/relation/"; var expected = { object: "relation" }; - assert.deepEqual(toTest(simpleRelationStringTrail), expectedi); + assert.deepEqual(toTest(simpleRelationStringTrail), expected); test.finish(); } @@ -78,20 +78,20 @@ module.exports = , 'tag with two values': function(test) { test.ok(true); var nodeWithTwoValues = "/node[tag=foo|bar]"; - var expected = { object: "node", tag: { key:["key"], value:["foo", "bar"]}}; + var expected = { object: "node", tag: { key:["tag"], value:["foo", "bar"]}}; assert.deepEqual(toTest(nodeWithTwoValues), expected); test.finish(); } , 'tag with two keys': function(test) { test.ok(true); - var nodeWithTwoKeys = "/node[foo,bar=value]"; + var nodeWithTwoKeys = "/node[foo|bar=value]"; var expected = { object: "node", tag: { key:["foo", "bar"], value:["value"]}}; assert.deepEqual(toTest(nodeWithTwoKeys), expected); test.finish(); } , 'tags with cross product': function(test) { test.ok(true); - var tagCrossProduct = "/node[key1,key2=value1,value2]"; + var tagCrossProduct = "/node[key1|key2=value1|value2]"; var expected = { object: "node", tag: {key:["key1", "key2"], value:["value1", "value2"]}}; assert.deepEqual(toTest(tagCrossProduct), expected); test.finish(); diff --git a/src/nodejs/tests/urlToResObj.js b/src/nodejs/tests/urlToResObj.js new file mode 100644 index 0000000..b45edfd --- /dev/null +++ b/src/nodejs/tests/urlToResObj.js @@ -0,0 +1,63 @@ +var assert = require('assert'); +var test = require('../parse.js'); + + +//TODO function does not exist yet +var toTest = test.urlToXpathObj; + + +// test all simple objects { node, way, relation } + +var simpleNodeString = "/node"; +var expected = { object: "node" }; +assert.deepEqual(toTest(simpleNodeString), expected); + +var simpleNodeStringTrail = "/node/"; +var expected = { object: "node" }; +assert.deepEqual(toTest(simpleNodeStringTrail), expected); + +var simpleWayString = "/way"; +var expected = { object: "way" }; +assert.deepEqual(toTest(simpleWayString), expected); + +var simpleWayStringTrail = "/way/"; +var expected = { object: "way" }; +assert.deepEqual(toTest(simpleWayStringTrail), expected); + +var simpleRelationString = "/relation"; +var expected = { object: "relation" }; +assert.deepEqual(toTest(simpleRelationString), expected); + +var simpleRelationStringTrail = "/relation/"; +var expected = { object: "relation" }; +assert.deepEqual(toTest(simpleRelationStringTrail), expected); + +// TODO invalid object eg not (node, way, relation) + +var nodeWithBbox = "/node[bbox=0,51.5,0.25,51.75]"; +var expected = { object: "node", bbox: {left:0, bottom:51.5, right:0.25, top:51.75} }; +assert.deepEqual(toTest(nodeWithBbox), expected); + +var nodeWithSimpleTag = "/node[key=value]"; +var expected = { object: "node", tag: { key:["key"], value:["value"]}}; +assert.deepEqual(toTest(nodeWithSimpleTag), expected); + +var nodeWithTwoValues = "/node[tag=foo|bar]"; +var expected = { object: "node", tag: { key:["key"], value:["foo", "bar"]}}; +assert.deepEqual(toTest(nodeWithTwoValues), expected); + +var nodeWithTwoKeys = "/node[foo,bar=value]"; +var expected = { object: "node", tag: { key:["foo", "bar"], value:["value"]}}; +assert.deepEqual(toTest(nodeWithTwoKeys), expected); + +var tagCrossProduct = "/node[key1,key2=value1,value2]"; +var expected = { object: "node", tag: {key:["key1", "key2"], value:["value1", "value2"]}}; +assert.deepEqual(toTest(tagCrossProduct), expected); + +var nodeBboxTag = "/node[bbox=0,0,0,0][key=value]"; +var nodeTagBbox = "/node[bbox=0,0,0,0][key=value]"; +var expected = { object: "node", bbox: {left:0,bottom:0,right:0,top:0}, tag: {key:["key"], value:["value"]}}; +assert.deepEqual(toTest(nodeBboxTag), expected); +assert.deepEqual(toTest(nodeTagBbox), expected); + + diff --git a/src/nodejs/xmlGenerator.js b/src/nodejs/xmlGenerator.js index a477457..6ba0191 100644 --- a/src/nodejs/xmlGenerator.js +++ b/src/nodejs/xmlGenerator.js @@ -30,23 +30,24 @@ exports.createNode = function (node) { // FIXME: make this shit working exports.createWay = function (row) { - var way = builder.begin('way') + var xmlWay = builder.begin('way') .att('id', row.id) - .att('timestamp', toISO8601(row.tstamp)) + .att('timestamp', row.timestamp) .att('version', row.version) - .att('changeset', row.changeset_id); - if(row.tags != '{}') { - temp = row.tags.replace("{","").replace("}","").split(","); - for(var x=0;x<temp.length;x=x+2){ - way.ele('tag') - .att('k',escape(temp[x])) - .att('v',escape(temp[x+1])); - } - } - temp = row.nodes.replace("{","").replace("}","").split(","); - for(var i=0;i<temp.length;i++) { - way.ele('nd').att('ref',temp[i]); + .att('changeset', row.changeset); + + if(row.tags) { + row.tags.forEach(function(tuple){ + xmlWay.ele('tag') + .att('k',escape(tuple.key)) + .att('v',escape(tuple.value)); + }); } + + //temp = row.nodes.replace("{","").replace("}","").split(","); + //for(var i=0;i<temp.length;i++) { + // way.ele('nd').att('ref',temp[i]); + //} return builder.toString({pretty:'true'}); }; |