source: subversion/applications/editors/potlatch/relation.as @ 14695

Last change on this file since 14695 was 14695, checked in by richard, 11 years ago

change relation_member 'type' case, to match change in database

  • Property svn:executable set to *
File size: 14.5 KB
Line 
1
2        // =====================================================================================
3        // relations.as
4        // Potlatch relation-handling code
5        // =====================================================================================
6
7        // ** highlight isn't yellow if it's part of a relation (should be)
8        // ** default tags: type, name
9        // ** verboseText isn't very good
10
11        // =====================================================================================
12        // Classes - OSMRelation
13
14        function OSMRelation() {
15                this.members = new Array();
16                this.attr=new Array();
17                this.isHighlighting = false;
18                this.clean=true;                                        // altered since last upload?
19                this.uploading=false;                           // currently uploading?
20                this.locked=false;                                      // locked against upload?
21                this.version=0;
22        };
23        OSMRelation.prototype=new MovieClip();
24
25
26        // OSMRelation.verboseText - create long description of relation
27
28        OSMRelation.prototype.verboseText = function() {
29                var text = this._name+": ";
30                var type = undefined;
31                if ( this.attr['type'] ) {
32                        type = this.attr['type'];
33                        text += type + " ";
34                }
35
36                if ( type == 'route' ) {
37                        if ( this.attr['route'] )       text += this.attr['route'] + " ";
38                        if ( this.attr['network'] )     text += this.attr['network'] + " ";
39                        if ( this.attr['ref'] )         text += this.attr['ref']+" ";
40                        if ( this.attr['name'] )        text += this.attr['name']+" ";
41                        if ( this.attr['state'] )       text += "("+this.attr['state']+") ";
42                } else if ( this.attr['name'] ) text += this.attr['name'];
43
44                return text;
45        };
46
47        // OSMRelation.getType/getName - summary info used in property window
48
49        OSMRelation.prototype.getType=function() {
50                if (!this.attr['type']) { return "relation"; }
51                if (this.attr['type']=='route') {
52                        if (this.attr['network']) { return this.attr['network']; }
53                        if (this.attr['route']) { return this.attr['route']; }
54                }
55                return this.attr['type'];
56        };
57       
58        OSMRelation.prototype.getName=function() {
59                if (this.attr['ref' ]) { return this.attr['ref' ]; }
60                if (this.attr['name']) { return this.attr['name']; }
61                return '';
62        };
63
64        // OSMRelation.load - load from remote server
65
66        OSMRelation.prototype.load=function() {
67                responder = function() { };
68                responder.onResult = function(result) {
69                        _root.relsreceived+=1;
70                        var w=result[0];
71                        var i,id;
72                        _root.map.relations[w].clean=true;
73                        _root.map.relations[w].locked=false;
74                        _root.map.relations[w].attr=result[1];
75                        _root.map.relations[w].members=result[2];
76                        _root.map.relations[w].version=result[3];
77if (_root.chat._visible) {
78        _root.chat.text+="Loaded "+w+"("+result[3]+"): "+result[2]+"\n";
79}
80                        _root.map.relations[w].redraw();
81                };
82                remote_read.call('getrelation',responder,Math.floor(this._name));
83        };
84
85        OSMRelation.prototype.reload=function() {
86                if ( this._name < 0 )
87                        this.removeMovieClip();
88                else {
89                        _root.relsrequested++;
90                        this.load();
91                }
92        };
93
94        // OSMRelation.upload - save to remote server
95
96        OSMRelation.prototype.upload=function() {
97                putresponder=function() { };
98                putresponder.onResult=function(result) {
99                        var code=result.shift(); if (code) { handleError(code,result); return; }
100                        var nw=result[1];       // new relation ID
101                        if (result[0]!=nw) {
102                                _root.map.relations[result[0]]._name=nw;
103                        }
104                        _root.map.relations[nw].uploading=false;
105                        _root.map.relations[nw].version=result[2];
106                        _root.writesrequested--;
107                };
108
109                // ways/nodes for negative IDs should have been previously put
110                // so the server should know about them
111                if (!this.uploading && !this.locked && !_root.sandbox ) {
112                        this.uploading=true;
113                        _root.writesrequested++;
114                        remote_write.call('putrelation', putresponder,
115                                _root.usertoken, _root.changeset, this.version,
116                                Math.floor(this._name),
117                                this.attr, this.members, 1);
118                        this.clean=true;
119                }
120        };
121
122
123        // OSMRelation.redraw           - show on map
124        // OSMRelation.drawPoint
125        // OSMRelation.setHighlight
126
127        OSMRelation.prototype.redraw=function() {
128                this.createEmptyMovieClip("line",1);                                    // clear line
129                var linewidth=Math.max(_root.linewidth*3,10);
130                var linealpha= this.isHighlighting ? 75 : 50;
131                var c = this.isHighlighting ? 0xff8800 : 0x8888ff;
132
133                var type = this.getType();
134                if ( !this.isHighlighting ) {
135                        if ( relcolours[type] != undefined ) {
136                                c = relcolours[type]; linewidth = relwidths[type]; linealpha = relalphas[type];
137                        }
138                }
139                this.line.lineStyle(linewidth,c,linealpha,false,"none");
140
141                var ms = this.members;
142                for ( var m = 0; m < ms.length; m++ ) {
143                        if ( ms[m][0] == 'Way' && _root.map.ways[ms[m][1]] ) {
144                                var way = _root.map.ways[ms[m][1]];
145               
146                                this.line.moveTo(way.path[0].x,way.path[0].y);
147                                for (var i=1; i<way.path.length; i+=1) {
148                                        this.line.lineTo(way.path[i].x,way.path[i].y);
149                                }
150                        } else if ( ms[m][0] == 'Node' && _root.map.pois[ms[m][1]] ) {
151                                var poi = _root.map.pois[ms[m][1]];
152                                this.drawPoint(poi._x, poi._y);
153                        } else if ( ms[m][0] == 'Node' ) {
154                                this.drawPoint(nodes[ms[m][1]].x,nodes[ms[m][1]].y);
155                        }
156                }
157        };
158
159        OSMRelation.prototype.drawPoint = function(x, y) {
160                var z = Math.max(100/Math.pow(2,_root.scale-13),6.25)/30;
161                this.line.moveTo(x-z,y-z);
162                this.line.lineTo(x-z,y+z);
163                this.line.lineTo(x+z,y+z);
164                this.line.lineTo(x+z,y-z);
165                this.line.lineTo(x-z,y-z);
166        };
167
168        OSMRelation.prototype.setHighlight = function(highlight) {
169                if ( this.isHighlighting == highlight )
170                        return;
171
172                this.isHighlighting = highlight;
173                this.redraw();
174        };
175
176        // ---- Editing and information functions
177
178        OSMRelation.prototype.getWayRole=function(way_id) {
179                return this.getRole('Way', way_id);
180        };
181
182        OSMRelation.prototype.getRole=function(type, id) {
183                var ws = this.members;
184                var role;
185                for ( var m = 0; m < ws.length && role == undefined; m++ ) {
186                        if ( ws[m][0] == type && ws[m][1] == id ) {
187                                role = ws[m][2];
188                        }
189                }
190                return role;
191        };
192
193        OSMRelation.prototype.renumberMember=function(type, id, new_id) {
194                var ws = this.members;
195                var set = false;
196                for ( var m = 0; m < ws.length && !set; m++ ) {
197                        if ( ws[m][0] == type && ws[m][1] == id ) {
198                                ws[m][1] = new_id;
199                                set = true;
200                        }
201                }
202        };
203
204        OSMRelation.prototype.setRole=function(type, id, role) {
205                var ws = this.members;
206                var set = false;
207                var diff = true;
208                for ( var m = 0; m < ws.length && !set; m++ ) {
209                        if ( ws[m][0] == type && ws[m][1] == id ) {
210                                diff = (ws[m][2] != role);
211                                ws[m][2] = role;
212                                set = true;
213                        }
214                }
215                if ( !set )
216                        this.members.push([type, id, role]);
217                if ( diff ) {
218                        this.clean = false;
219                        this.redraw();
220                }
221        };
222
223        OSMRelation.prototype.setWayRole=function(way_id, role) {
224                this.setRole('Way', way_id, role);
225        };
226
227        OSMRelation.prototype.hasWay=function(way_id) {
228                var role = this.getWayRole(way_id);
229                return role == undefined ? false : true;
230        };
231
232        OSMRelation.prototype.getNodeRole=function(node_id) {
233                return this.getRole('Node', node_id);
234        };
235
236        OSMRelation.prototype.setNodeRole=function(node_id, role) {
237                this.setRole('Node', node_id, role);
238        };
239
240        OSMRelation.prototype.hasNode=function(node_id) {
241                var role = this.getNodeRole(node_id);
242                return role == undefined ? false : true;
243        };
244
245        OSMRelation.prototype.removeMember=function(type, id) {
246                this.removeMemberDirty(type, id, true);
247        };
248
249        OSMRelation.prototype.removeMemberDirty=function(type, id, markDirty) {
250                var ws = this.members;
251                for (var m in ws) {
252                        if ( ws[m][0] == type && ws[m][1] == id ) {
253                                ws.splice(m, 1);
254                                if ( markDirty )
255                                        this.clean = false;
256                                this.redraw();
257                        }
258                }
259        };
260
261        OSMRelation.prototype.removeWay=function(way_id) {
262                this.removeMember('Way', way_id);
263        };
264
265        OSMRelation.prototype.removeNode=function(node_id) {
266                this.removeMember('Node', node_id);
267        };
268
269        // ----- UI
270
271        OSMRelation.prototype.editRelation = function() {
272                var rel = this;
273                var completeEdit = function() {
274                        rel.setHighlight(false);
275                        _root.panel.properties.reinit();
276                };
277
278                rel.setHighlight(true);
279                _root.panel.properties.enableTabs(false);
280               
281                _root.windows.attachMovie("modal","relation",++windowdepth);
282                _root.windows.relation.init(402, 255, ["OK"], completeEdit);
283                var z=5;
284                var box=_root.windows.relation.box;
285               
286                box.createTextField("title",z++,7,7,400-14,20);
287                with (box.title) {
288                        type='dynamic';
289                        text=this._name; setTextFormat(plainText);
290                        setNewTextFormat(boldText); replaceSel("Relation ");
291                }
292
293                // Light grey background
294                box.createEmptyMovieClip('lightgrey',z++);
295                with (box.lightgrey) {
296                        beginFill(0xF3F3F3,100);
297                        moveTo(10,30); lineTo(392,30);
298                        lineTo(392,213); lineTo(10,213);
299                        lineTo(10,30); endFill();
300                };
301
302                box.attachMovie("propwindow","properties",z++);
303                with (box.properties) { _x=14; _y=34; };
304                _root.editingrelation = this;
305                box.properties.ynumber = 9;
306                box.properties.init("relation",2,9);
307
308                box.attachMovie("newattr", "newattr", z++);
309                with ( box.newattr ) {
310                        _x = 400-16; _y = 18;
311                }
312                box.newattr.onRelease =function() { box.properties.enterNewAttribute(); };
313                box.newattr.onRollOver=function() { setFloater(iText("Add a new tag",'tip_addtag')); };
314                box.newattr.onRollOut =function() { clearFloater(); };
315        };
316
317        Object.registerClass("relation",OSMRelation);
318
319
320        // ===============================
321        // Support functions for relations
322
323function debugRelations() {
324        _root.chat._visible=true;
325        _root.chat.text="";
326        var rels = _root.map.relations;
327        for (var r in rels) {
328                _root.chat.text+=r+": "+rels[r].members+"\n";
329                showObjects(rels[r].attr,0);
330        }
331}
332
333        function redrawRelationsForMember(type, id) {
334                var rels = type == 'Way' ? getRelationsForWay(id) : getRelationsForNode(id);
335                for ( r in rels )
336                        _root.map.relations[rels[r]].redraw();
337        }
338
339        function memberDeleted(type, id) {
340                var rels = _root.map.relations;
341                for ( r in rels )
342                        rels[r].removeMemberDirty(type, id, true);
343        }
344
345        function renumberMemberOfRelation(type, id, new_id) {
346                var rels = _root.map.relations;
347                for ( r in rels )
348                        rels[r].renumberMember(type, id, new_id);
349        }
350
351        function getRelationsForWay(way) {
352                var rels = [];
353                var z = _root.map.relations;
354                for ( var i in z ) {
355                        if ( z[i].hasWay(way) )
356                                rels.push(i);
357                }
358                return rels;
359        }
360
361        function getRelationsForNode(node) {
362                var rels = [];
363                var z = _root.map.relations;
364                for ( var i in z ) {
365                        if ( z[i].hasNode(node) )
366                                rels.push(i);
367                }
368                return rels;
369        }
370       
371        function markWayRelationsDirty(way) {
372                var z=_root.map.relations;
373                for (var i in z) {
374                        if (z[i].hasWay(way)) { z[i].clean=false; }
375                }
376                var p=_root.map.ways[way].path;
377                for (var i in p) { markNodeRelationsDirty(_root.map.ways[way].path[i].id); }
378        }
379       
380        function markNodeRelationsDirty(node) {
381                var z=_root.map.relations;
382                for (var i in z) {
383                        if (z[i].hasNode(node)) { z[i].clean=false; }
384                }
385        }
386
387        function uploadDirtyRelations() {
388                var rs = _root.map.relations;
389                for ( var i in rs ) {
390                        if ( !rs[i].clean ) {
391                                rs[i].upload();
392                        }
393                }
394        }
395
396        function revertDirtyRelations() {
397                var rs = _root.map.relations;
398                for ( var i in rs ) {
399                        if ( !rs[i].clean ) {
400                                rs[i].reload();
401                        }
402                }
403        }
404
405        // addToRelation - add a way/point to a relation
406        //                                 called when user clicks '+' relation button
407
408        function addToRelation() {
409                var proptype = _root.panel.properties.proptype;
410                var type, id;
411                switch (proptype) {
412                        case 'way':             type='Way' ; id=wayselected; break;
413                        case 'point':   type='Node'; id=_root.ws.path[_root.pointselected].id; break;
414                        case 'POI':             type='Node'; id=poiselected; break;
415                }
416                if ( type == undefined || id == undefined ) return;
417
418                var completeAdd = function(button) {
419
420                        if ( button != iText("Ok",'ok') ) return false;
421
422                        var box=_root.windows.relation.box;
423                        var radio=box.reloption.selected;
424                        var keepDialog = false;
425
426                        switch (radio) {
427                                case 1: // Add to an existing relation
428                                                var selected=box.addroute_menu.selected;
429                                                var rs=_root.map.relations;
430                                                var i=0;
431                                                for (var r in rs) {
432                                                        if (selected==i) { 
433                                                        rs[r].setRole(type, id, ''); }
434                                                        i++;
435                                                }
436                                                break;
437                                case 2: // Create a new relation
438                                                var nid = newrelid--;
439                                                _root.map.relations.attachMovie("relation",nid,++reldepth);
440                                                _root.map.relations[nid].setRole(type, id, '');
441                                                _root.map.relations[nid].attr['type'] = undefined;
442                                                _root.windows.relation.remove(); keepDialog = true;
443                                                _root.map.relations[nid].editRelation();
444                                                break;
445                                case 3: // Find a relation
446                                                keepDialog=true;
447                                                if (box.search.text!='') {
448                                                        findresponder=function() {};
449                                                        findresponder.onResult=function(rellist) {
450                                                                for (r in rellist) {
451                                                                        var w=rellist[r][0];
452                                                                        if (!_root.map.relations[w]) {
453                                                                                _root.map.relations.attachMovie("relation",w,++reldepth);
454                                                                                _root.map.relations[w].attr=rellist[r][1];
455                                                                                _root.map.relations[w].members=rellist[r][2];
456                                                                                _root.relcount++;
457                                                                        }
458                                                                }
459                                                                createRelationMenu(_root.windows.relation.box,20);
460                                                                _root.windows.relation.box.search.text='';
461                                                        };
462                                                        remote_read.call('findrelations',findresponder,box.search.text);
463                                                }
464                                                break;
465                        }
466                        _root.panel.properties.reinit();
467                        if (keepDialog) { _root.panel.properties.enableTabs(false); }
468                        return keepDialog;
469                };
470
471                // Create dialogue
472
473                _root.panel.properties.enableTabs(false);
474                _root.windows.attachMovie("modal","relation",++windowdepth);
475                _root.windows.relation.init(300, 150, [iText("Cancel",'cancel'), iText("Ok",'ok')], completeAdd);
476                var z = 5;
477                var box = _root.windows.relation.box;
478               
479                box.createTextField("title",z++,7,7,300-14,20);
480                box.title.text = iText("Add $1 to a relation",'prompt_addtorelation',proptype);
481                with (box.title) {
482                        wordWrap=true;
483                        setTextFormat(boldText);
484                        selectable=false; type='dynamic';
485                }
486               
487                box.createTextField("instr",z++,7,30,300-14,40);
488
489                // Create radio buttons and menu
490
491                box.attachMovie("radio","reloption",z++);
492                box.reloption.addButton(10,35,iText("Add to an existing relation",'existingrelation'));
493                box.reloption.addButton(10,75,iText("Create a new relation",'createrelation'));
494                box.reloption.addButton(10,95,iText("Find a relation containing",'findrelation'));
495
496                createRelationMenu(box,20);
497
498                var w=box.reloption[3].prompt._width+25;
499                box.createTextField("search",z++,w,90,290-w,17);
500                box.search.setNewTextFormat(plainSmall);
501                box.search.type='input';
502                box.search.backgroundColor=0xDDDDDD;
503                box.search.background=true;
504                box.search.border=true;
505                box.search.borderColor=0xFFFFFF;
506                box.search.onSetFocus=function() { this._parent.reloption.select(3); };
507        }
508
509        function createRelationMenu(box,z) {
510                var relations=new Array();
511                var rs = _root.map.relations;
512                for ( var r in rs ) {
513                        relations.push(rs[r].verboseText());
514                }
515
516                if (relations.length==0) {
517                        relations.push(iText("No relations in current area",'norelations'));
518                        box.reloption.disable(1);
519                        box.reloption.select(2);
520                } else {
521                        box.reloption.enable(1);
522                        box.reloption.select(1);
523                }
524                box.attachMovie("menu", "addroute_menu", z);
525                box.addroute_menu.init(25, 50, 0, relations,
526                                        iText('Add to the chosen route','tip_selectrelation'),null, null, 268);
527        }
Note: See TracBrowser for help on using the repository browser.