Projet

Général

Profil

Paste
Télécharger (31,2 ko) Statistiques
| Branche: | Révision:

root / js / pano.js @ d4e538ff

1
if (img_prefix == undefined) var img_prefix = 'http://pano.tetaneutral.net/data/tsf2/vpongnian/tiles/ttn_mediatheque/mediatheque_70';
2
if (title == undefined) var title = 'point non défini';
3
if (to_cap == undefined) var to_cap = 0;
4
if (to_ele == undefined) var to_ele = 0;
5
if (to_zoom == undefined) var to_zoom = 0;
6
if (cap == undefined) var cap = 0;
7
if (cap_min == undefined) var cap_min = cap;
8
if (cap_max == undefined) var cap_max = cap_min+360;
9
if (ref_points == undefined) var ref_points = new Array();
10
if (image_loop == undefined) var image_loop = false;
11

    
12
var debug_mode = false;
13
var canvas;
14
var cntext;
15
var point_list = new Array();
16
var zoom = 0;
17
var zooms = new Array();
18
var prev_zm;
19
var zm;
20
var tile = {width:256, height:256};
21
var ntiles = {x:228, y:9};
22
var border_width = 2;
23
var imageObj = new Array();
24

    
25
var last  = {x:0,y:0};
26
var shift = {x:0,y:0};
27
var mouse = {x:0,y:0};
28
var speed = {x:0,y:0};
29
var canvas_pos = {x:0,y:0};
30
var tmt;
31
var is_located = false;
32
var point_colors = {
33
        'pano_point' : '255,128,128', // red
34
        'ref_point'  : '128,128,255', // blue
35
        'loc_point'  : '128,255,128', // green
36
        'temporary'  : '255,255,128', // yellow
37
        'unlocated'  : '255,255,255'  // white
38
};
39
var test = {x:0, y:0, i:100};
40

    
41

    
42
function getXMLHttpRequest() {
43
        var xhr = null;
44
        
45
        if (window.XMLHttpRequest || window.ActiveXObject) {
46
                if (window.ActiveXObject) {
47
                        try {
48
                                xhr = new ActiveXObject("Msxml2.XMLHTTP");
49
                        } catch(e) {
50
                                xhr = new ActiveXObject("Microsoft.XMLHTTP");
51
                        }
52
                } else {
53
                        xhr = new XMLHttpRequest(); 
54
                }
55
        } else {
56
                alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
57
                return null;
58
        }
59
        
60
        return xhr;
61
}
62

    
63

    
64

    
65
function nmodulo(val, div) {                // pour obtenir un modulo dans l'espace des nombres naturels N.
66
    return Math.floor((val%div+div)%div);   // il y a peut être plus simple, mais en attendant ....
67
}
68

    
69
function fmodulo(val, div) {                // pour obtenir un modulo dans l'espace des nombres réels positifs.
70
    return (val%div+div)%div;               // il y a peut être plus simple, mais en attendant ....
71
}
72

    
73
function distort_canvas(p, x, y) {
74
    if (p == 0) distort = 0;
75
    else {
76
        cntext.save();
77
        distort++;
78
        cntext.clearRect(0, 0, canvas.width, 2*canvas.height);
79
        var ratio = (canvas.width-2*distort)/canvas.width;
80
        var shift = canvas.height/2*(1-ratio);
81
        cntext.scale(1, ratio);
82
        if (p == 1) cntext.translate(0, 0);
83
        else if (p == -1) cntext.translate(0, 0);
84
        draw_image(x, y);
85
        cntext.restore();
86
        document.getElementById('res').innerHTML = 'distort : ' + distort + ' shift ' + shift + ' ratio : ' + ratio + '<br/>';
87
    }
88
}
89

    
90
function draw_image(ox, oy) {
91
    var ref_vals  = {x:last.x, y:last.y, zoom:zoom};
92
    ox = nmodulo(ox-canvas.width/2, zm.im.width);        // pour placer l'origine au centre du canvas
93
    oy = Math.floor(oy-canvas.height/2);                 // pas de rebouclage vertical
94

    
95
    cntext.clearRect(0, 0, canvas.width, canvas.height);
96
    cntext.fillStyle = "rgba(128,128,128,0.8)";
97

    
98
    if (canvas.height > zm.im.height) {
99
        var fy = Math.floor((oy+canvas.height/2-zm.im.height/2)/(tile.height*zm.ntiles.y))*zm.ntiles.y;
100
        if (fy < 0) fy = 0;
101
        var ly = fy + zm.ntiles.y;
102
    } else {
103
        var fy = Math.floor(oy/tile.height);
104
        var ly = Math.floor((oy+canvas.height+tile.height-1)/tile.height+1);
105
        if (fy < 0) fy = 0;
106
        if (ly > zm.ntiles.y) ly = zm.ntiles.y;
107
    }
108

    
109
    for (var j=fy; j<ly; j++) {
110
        var delta_y = (Math.floor(j/zm.ntiles.y) - Math.floor(fy/zm.ntiles.y)) * (tile.height - zm.last_tile.height);
111
        var dy = j*tile.height - oy - delta_y;
112
        var ny = j%ntiles.y;
113
        var wy = zm.tile.width;
114
        if (ny == zm.ntiles.y - 1) wy = zm.last_tile.height;
115

    
116
        var cpx = 0;
117
        var i = 0;
118
        var Nx = zm.ntiles.x;
119
        while (cpx < ox+canvas.width) {
120
            var cur_width = zm.tile.width;
121
            if (i%Nx == zm.ntiles.x-1) cur_width = zm.last_tile.width;
122
            if (cpx >= ox-cur_width) {
123
                var nx = i%Nx;
124
                var idx = nx+'-'+ny+'-'+ref_vals.zoom;
125
                if (imageObj[idx] && imageObj[idx].complete) {
126
                    draw_tile(idx, cpx-ox, dy); // l'image est déja en mémoire, on force le dessin sans attendre.
127
                } else {
128
                    var fname = get_file_name(nx, ny, ref_vals.zoom);
129
                    imageObj[idx] = new Image();
130
                    imageObj[idx].src = fname;
131
                    var ts = zm.get_tile_size(nx, ny);
132
                    cntext.fillRect(cpx-ox, dy, ts.width, ts.height);
133
                    imageObj[idx].addEventListener('load', (function(ref, idx, dx, dy, ox, oy, ts) {
134
                        return function() {        // closure nécéssaire pour gestion assynchronisme !!!
135
                            draw_tile_del(ref, idx, dx, dy, ox, oy, ts.width, ts.height);
136
                        };
137
                    })(ref_vals, idx, cpx-ox, dy, ox, oy, ts), false);
138
                }
139
//                load_image(zoom, nx, ny, shx, shy, cpx-ox, dy, ox, oy);
140
            }
141
            cpx += cur_width;
142
            i++;
143
        }
144
    }
145
    drawDecorations(ox, oy);
146
    var cap_ele = zm.get_cap_ele(last.x, zm.im.height/2-last.y);
147
    angle_control.value = cap_ele.cap.toFixed(2);
148
    elvtn_control.value = cap_ele.ele.toFixed(2);
149
}
150

    
151
function draw_tile_del(ref, idx, tx, ty, ox, oy, twidth, theight) {
152
    if (ref.zoom == zoom && ref.x == last.x && ref.y == last.y) {
153
        draw_tile(idx, tx, ty);
154
        drawDecorations(ox, oy, tx, ty, twidth, theight);
155
    }
156
}
157

    
158
function draw_tile(idx, ox, oy) {
159
    var img = imageObj[idx];
160
    cntext.drawImage(img, ox, oy);
161
}
162

    
163
function drawDecorations(ox, oy, tx, ty, twidth, theight) {
164
    if (twidth) {
165
        cntext.save();
166
        cntext.beginPath();
167
        cntext.rect(tx, ty, twidth, theight);
168
        cntext.clip();
169
    }
170
    var wgrd = zm.im.width/360;
171
    var od = ((ox+canvas.width/2)/wgrd)%360;
172
    var el = (zm.im.height/2 - (oy+canvas.height/2))/wgrd;
173
    cntext.fillStyle = "rgba(0,128,128,0.9)";
174
    cntext.strokeStyle = "rgb(255,255,255)";
175
    cntext.lineWidth = 1;
176
    cntext.fillRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
177
    cntext.strokeRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
178
    for(var i = 0; i < zm.pt_list.length; i++) {
179
        if (zm.pt_list[i]['type'] != 'unlocated') {
180
            cntext.fillStyle = 'rgba('+point_colors[zm.pt_list[i]['type']]+',0.5)';
181
            var cx = nmodulo(zm.pt_list[i]['xc'] - ox, zm.im.width);
182
            var cy = zm.pt_list[i]['yc'] - oy;
183
            cntext.beginPath();
184
            cntext.arc(cx, cy, 20, 0, 2*Math.PI, true);
185
            cntext.fill();
186
        }
187
    }
188

    
189
    if (twidth) {
190
        cntext.restore();
191
    }
192

    
193
}
194

    
195
function insert_drawn_point(lat, lon, alt) {
196
    var rt = 6371;  // Rayon de la terre
197
    var pt_alt = document.getElementById('pos_alt').childNodes[0].nodeValue;
198
    var pt_lat = document.getElementById('pos_lat').childNodes[0].nodeValue;
199
    var pt_lon = document.getElementById('pos_lon').childNodes[0].nodeValue;
200

    
201
    var alt1 = pt_alt;
202
    var lat1 = pt_lat*Math.PI/180;
203
    var lon1 = pt_lon*Math.PI/180;
204
    var alt2 = alt;
205
    var lat2 = lat*Math.PI/180;
206
    var lon2 = lon*Math.PI/180;
207

    
208
    var dLat = lat2-lat1;
209
    var dLon = lon2-lon1;
210

    
211
    var a = Math.sin(dLat/2)*Math.sin(dLat/2) + Math.sin(dLon/2)*Math.sin(dLon/2)*Math.cos(lat1)*Math.cos(lat2);  //
212
    var angle = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
213
    var d = angle*rt;                    // distance du point en Kms
214

    
215
    var y = Math.sin(dLon) * Math.cos(lat2);
216
    var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
217
    var cap = Math.atan2(y,x);                 // cap pour atteindre le point en radians
218
    var e = Math.atan2((alt2 - alt1)/1000 - d*d/(2*rt),d);  // angle de l'élévation en radians
219

    
220
    return {d:d, cap:cap*180/Math.PI, ele:e*180/Math.PI};   // les résultats sont en degrés
221
}
222

    
223
function localate_point() {
224
    var lat = document.getElementById("loca_latitude").value;
225
    var lon = document.getElementById("loca_longitude").value;
226
    var alt = document.getElementById("loca_altitude").value;
227
    if (lat == '' || isNaN(lat) || lat <= -90 || lat > 90) {
228
        alert("La latitude "+lat+"n'est pas correcte");
229
        return;
230
    }
231
    if (lat == '' || isNaN(lon) || lon <= -180 || lon > 180) {
232
        alert("La longitude "+lon+"n'est pas correcte");
233
        return;
234
    }
235
    if (lat == '' || isNaN(alt) || alt < -400 || alt > 10000000) {
236
        alert("l'altitude "+alt+"n'est pas correcte");
237
        return;
238
    }
239
    var opt_ced = new Array();
240
    opt_dce = insert_drawn_point(lat, lon, alt);
241
    display_temp(opt_dce.d, opt_dce.cap, opt_dce.ele);
242
}
243

    
244
function display_temp(d,cap,ele) {
245
    point_list[point_list.length] = new Array("point temporaire", d,cap,ele, "temporary");
246
    reset_zooms();
247
    putImage(last.x, last.y);
248
}
249

    
250
function arrayUnset(array, value){
251
    array.splice(array.indexOf(value), 1);
252
}
253

    
254
function erase_point() {
255
        for (var i=0; i<point_list.length; i++) {
256
                if(point_list[i][0] == "point temporaire"){
257
                        arrayUnset(point_list,point_list[i]);
258
                        loop = erase_point();
259
                }
260
        }
261
        reset_zooms();
262
    putImage(last.x, last.y);
263
}
264

    
265
function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position
266
    var prm = [z, x, y];
267
    var fname = img_prefix;
268
    for (var i = 0; i < prm.length; i++) {
269
        fname += '_';
270
        if (prm[i] < 10) fname += '00';
271
        else if (prm[i] < 100) fname += '0';
272
        fname += prm[i];
273
    }
274
    fname += '.jpg';
275
    return fname;
276
}
277

    
278
function get_base_name() {
279
        /** 
280
         * @returns the base name, which is the name (not path) of the folder where
281
         * the tiles are.
282
         */
283
        return img_prefix.split('/').reverse()[0];
284
}
285

    
286

    
287
function keys(key) {
288

    
289
    hide_links();
290
    evt = key || event;
291
    //evt.preventDefault();
292
    //evt.stopPropagation();
293
    if (!key) {
294
        key = window.event;
295
        key.which = key.keyCode;
296
    }
297
//    alert(key);
298
//    if (!evt.shiftKey) return;
299
    switch (key.which) {
300
    /*case 66: // b
301
        alert(key.pageX);
302
        test.x=tile.width*(ntiles.x-3);
303
        test.y=0;
304
        putImage(test.x, test.y);
305
        return;
306
    case 67: // c
307
        test.x=0;
308
        test.y=tile.height*(ntiles.y-3);
309
        putImage(test.x, test.y);
310
        return;*/
311
    case 36: // home
312
        putImage(0, zm.im.height/2);
313
        return;
314
    case 35: // end
315
        putImage(last.x+zm.im.width/2, last.y);
316
        return;
317
    case 39: // left
318
        putImage(last.x+40, last.y);
319
        return;
320
    case 40: // up
321
        putImage(last.x, last.y+20);
322
        return;
323
    case 37: // right
324
        putImage(last.x-40, last.y);
325
        return;
326
    case 38: // down
327
        putImage(last.x, last.y-20);
328
        return;
329
    case 33: // pageup
330
        zoom_control.value--;
331
        change_zoom()
332
        return;
333
    case 34: // pagedown
334
        zoom_control.value++;
335
        change_zoom()
336
        return;
337
    default:
338
//        alert(key.which)
339
        return;
340
    }
341
}
342

    
343
function onImageClick(e) {
344
    hide_contextmenu();
345
    shift.x = last.x;
346
    shift.y = last.y;
347
    speed.x = 0;
348
    speed.y = 0;
349
    mouse.x = e.pageX;
350
    mouse.y = e.pageY;
351
    clearTimeout(tmt);  //arrêt de l'éffet eventuel d'amorti en cours.
352
    canvas.addEventListener('mousemove', stickImage, false);
353
    canvas.addEventListener('mouseup', launchImage, false);
354
    //canvas.addEventListener('mouseout', launchImage, false);
355
    canvas.style.cursor='move';
356
    //document.onmousemove = stickImage;
357
    document.onmouseup = launchImage;
358
    hide_links();
359
}
360

    
361

    
362
function stickImage(e) {
363
    var xs = mouse.x - e.pageX + shift.x;
364
    var ys = mouse.y - e.pageY + shift.y;
365
    speed.x = xs - last.x;  //mémorisation des vitesses horizontales
366
    speed.y = ys - last.y;  //et verticales lors de ce déplacement
367
    putImage(xs, ys);
368
}
369

    
370
function launchImage(e) {
371
    distort_canvas(0);
372
    canvas.removeEventListener('mousemove', stickImage, false);
373
    //document.onmousemove = null;
374
    shift.x = e.pageX - mouse.x + shift.x;
375
    shift.y = e.pageY - mouse.y + shift.y;
376
    tmt = setTimeout(inertialImage, 100);
377
}
378

    
379
function putImage(x, y) { // est destiné à permettre l'effet d'amortissement par la mémorisation de la position courante.
380
    if (!zm.is_updated) return;
381
    if (x >= zm.im.width) {   // rebouclage horizontal
382
        shift.x -= zm.im.width;
383
        x -= zm.im.width;
384
    } else if (x < 0) {
385
        shift.x += zm.im.width;
386
        x += zm.im.width;
387
    }
388
    if (y >= zm.im.height) {   // pas de rebouclage vertical mais blocage
389
        //distort_canvas(1, x, y);
390
        shift.y = zm.im.height-1;
391
        y = zm.im.height-1;
392
    } else if (y < 0) {
393
        //distort_canvas(-1, x, y);
394
        shift.y = 0;
395
        y = 0;
396
    }
397

    
398
    last.x = x;
399
    last.y = y;
400
    draw_image(x, y);
401
}
402

    
403
function inertialImage() {
404
    speed.x *= 0.9;
405
    speed.y *= 0.9;
406
    if (Math.abs(speed.x) > 2 || Math.abs(speed.y) > 2) {
407
        putImage(last.x+speed.x, last.y+speed.y);
408
        tmt = setTimeout(inertialImage, 100);
409
    } else {
410
        show_links();
411
    }
412
}
413

    
414
function tri_ref_points(v1, v2) {
415
    return v1['x'] - v2['x'];
416
}
417

    
418

    
419

    
420
function tzoom(zv) {
421
    this.value = zv;
422
    this.ntiles = {x:0,y:0};
423
    this.tile = {width:0,height:0};
424
    this.last_tile = {width:0,height:0};
425
    this.max_tile = {width:0,height:0};
426
    this.im = {width:0,height:0};
427
    this.is_updated = false;
428

    
429
    this.refresh = function() {
430
        this.im.visible_width = this.tile.width*(this.ntiles.x-1)+this.last_tile.width;
431
        this.is_updated = true;
432

    
433
        this.im.width = this.im.visible_width;
434
        this.im.height = this.tile.height*(this.ntiles.y-1)+this.last_tile.height;
435
        if (this.last_tile.width > this.tile.width) this.max_tile.width = this.im.last_tile.width;
436
        else this.max_tile.width = this.tile.width;
437
        if (this.last_tile.height > this.tile.height) this.max_tile.height = this.im.last_tile.height;
438
        else this.max_tile.height = this.tile.height;
439

    
440
        var ord_pts = new Array();
441
        i=0;
442
        for(var label in ref_points) {
443
            ord_pts[i++] = ref_points[label]
444
        }
445
        ord_pts = ord_pts.sort(tri_ref_points);
446
        is_located = i > 1 || image_loop && i > 0;
447

    
448
        var alpha_domain = {start:0, end:360};
449
        this.pixel_y_ratio = this.im.width/360;
450
        if (is_located) {
451
            this.ref_pixels = new Array;
452
            this.ref_pixels[0] = new Array();    // Attention il faut compter un intervalle de plus !
453
            for (var i=0; i < ord_pts.length; i++) { // premier parcours pour les paramètres cap/x
454
                this.ref_pixels[i+1] = new Array();
455
                this.ref_pixels[i+1].x = Math.floor(ord_pts[i].x*this.im.width);
456
                this.ref_pixels[i+1].cap = fmodulo(ord_pts[i].cap, 360);
457
                if (i != ord_pts.length-1) {
458
                    this.ref_pixels[i+1].ratio_x = (ord_pts[i+1].x - ord_pts[i].x)/fmodulo(ord_pts[i+1].cap - ord_pts[i].cap, 360)*this.im.width;
459
                }
460
            }
461
            if (image_loop == true) {
462
                var dpix = this.im.width;
463
                var dangle = 360;
464
                if (ord_pts.length > 1) {
465
                    dpix = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
466
                    dangle = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[this.ref_pixels.length-1].cap, 360);
467
                }
468
                this.ref_pixels[0].ratio_x = dpix/dangle;
469
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[0].ratio_x;
470
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
471
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[ord_pts.length].cap + dpix / this.ref_pixels[0].ratio_x, 360);
472
            } else {
473
                this.ref_pixels[0].ratio_x = this.ref_pixels[1].ratio_x;
474
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[ord_pts.length-1].ratio_x;
475
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[1].x / this.ref_pixels[1].ratio_x, 360);
476
                alpha_domain.start = this.ref_pixels[0].cap;
477
                alpha_domain.end = fmodulo(this.ref_pixels[ord_pts.length].cap+(this.im.width-this.ref_pixels[ord_pts.length].x)/this.ref_pixels[ord_pts.length].ratio_x, 360);
478
                this.pixel_y_ratio = this.im.width/fmodulo(alpha_domain.end-alpha_domain.start, 360);
479
            }
480
            this.ref_pixels[0].x = 0;
481

    
482
            for (var i=0; i < ord_pts.length; i++) { // second parcours pour les paramètres elevation/y
483
                this.ref_pixels[i+1].shift_y = Math.floor(this.pixel_y_ratio*ord_pts[i].ele - ord_pts[i].y*this.im.height);
484
                if (i != ord_pts.length-1) {
485
                    var next_shift = Math.floor(this.pixel_y_ratio*ord_pts[i+1].ele - ord_pts[i+1].y*this.im.height);
486
                    this.ref_pixels[i+1].dshft_y = (next_shift - this.ref_pixels[i+1].shift_y)/(this.ref_pixels[i+2].x - this.ref_pixels[i+1].x);
487
                }
488
            }
489

    
490
            if (image_loop == true) {
491
                var dpix  = this.im.width;
492
                var delt = 0;
493
                if (ord_pts.length > 1) {
494
                    dpix  = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
495
                    delt = this.ref_pixels[this.ref_pixels.length-1].shift_y - this.ref_pixels[1].shift_y;
496
                }
497
                this.ref_pixels[0].dshft_y = -delt/dpix;
498
                this.ref_pixels[ord_pts.length].dshft_y = this.ref_pixels[0].dshft_y;
499
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
500
                this.ref_pixels[0].shift_y = this.ref_pixels[ord_pts.length].shift_y + dpix*this.ref_pixels[0].dshft_y;
501
            } else {
502
                this.ref_pixels[0].shift_y = this.ref_pixels[1].shift_y;
503
                this.ref_pixels[0].dshft_y = 0;
504
                this.ref_pixels[ord_pts.length].dshft_y = 0;
505
            }
506

    
507
            if (debug_mode) {
508
                var res = document.getElementById('res');
509
                res.innerHTML = 'liste des '+this.ref_pixels.length+' valeurs de correction (image = '+this.im.width+'x'+this.im.height+') zoom = '+this.value+':<br/>';
510
                for (var i=0; i < this.ref_pixels.length; i++) { // pour le debug
511
                    res.innerHTML += '<p>point '+i+' :</p><ul>';
512
                    for (var key in this.ref_pixels[i]) { // pour le debug
513
                        res.innerHTML += '<li>'+key + '['+i+'] = '+this.ref_pixels[i][key]+'</li>';
514
                    }
515
                    if (i != this.ref_pixels.length-1) {
516
                        var tx0 = this.ref_pixels[i+1].x-1;
517
                        //var ty0 = this.ref_pixels[i+1].shift_y;
518
                        var ty0 = 0;
519
                    } else {
520
                        var tx0 = this.im.width-1;
521
                        var ty0 = 0;
522
                    }
523
                    res.innerHTML += '</ul><p>test sur : '+tx0+','+ty0+'</p>';
524
                    var tst = this.get_cap_ele(tx0, ty0);
525
                    res.innerHTML += '<p>cap:'+tst.cap+', ele:'+tst.ele+'</p>';
526
                    var tst2 = this.get_pos_xy(tst.cap, tst.ele);
527
                    res.innerHTML += '</ul><p>x:'+tst2.x+', y:'+tst2.y+'</p>';
528
                }
529
            }
530
        }
531

    
532
        this.pt_list = new Array();
533
        for (var i=0; i<point_list.length; i++) {
534
            var lbl = point_list[i][0];
535
            var dst = point_list[i][1];
536
            var cap = point_list[i][2];
537
            var ele = point_list[i][3];
538
            var lnk = point_list[i][4];
539
            var typ = 'unlocated';
540
            var rxy = this.get_pos_xy(cap, ele);
541
            var is_visible = fmodulo(cap - alpha_domain.start, 360) <= fmodulo(alpha_domain.end - alpha_domain.start -0.0001, 360)+0.0001 && is_located;
542

    
543
            this.pt_list[i] = new Array();
544
            if (ref_points[lbl] != undefined) {
545
                typ = 'ref_point';
546
                if (!is_located) rxy = {x:ref_points[lbl].x*this.im.width, y:ref_points[lbl].y*this.im.height}
547
            } else if(lnk == '' && is_visible && lbl != 'point temporaire') {
548
                typ = 'loc_point';
549
            }else if(is_visible && lbl =='point temporaire') {
550
            typ = 'temporary';
551

    
552
            } else if(is_visible) {
553
                typ = 'pano_point';
554
                lnk += '&to_zoom='+this.value;
555
            }
556
            this.pt_list[i]['type'] = typ;
557
            this.pt_list[i]['cap'] = cap;
558
            this.pt_list[i]['ele'] = ele;
559
            this.pt_list[i]['dist'] = dst;
560
            this.pt_list[i]['label'] = lbl;
561
            this.pt_list[i]['lnk'] = lnk;
562
            this.pt_list[i]['xc'] = rxy.x;
563
            this.pt_list[i]['yc'] = Math.floor(this.im.height/2 - rxy.y);
564
        }
565
    }
566

    
567
    this.get_tile_size = function(nx, ny) {
568
        var res = {width:0, height:0};
569
        if (nx == this.ntiles.x-1) res.width = this.last_tile.width;
570
        else res.width = this.tile.width;
571
        if (ny == this.ntiles.y-1) res.height = this.last_tile.height;
572
        else res.height = this.tile.height;
573
        return res;
574
    }
575

    
576
    this.get_cap_ele = function(px, py) {               // recherche d'un cap et d'une élévation à partir d'un pixel X,Y.
577
        if (is_located) {
578
            for (var i=0; i < this.ref_pixels.length; i++) {
579
                if (i == this.ref_pixels.length - 1 || px < this.ref_pixels[i+1].x) {
580
                    var dpix = px-this.ref_pixels[i].x;
581
                    var cp = fmodulo(this.ref_pixels[i].cap + dpix/this.ref_pixels[i].ratio_x, 360);
582
                    var el = (py+this.ref_pixels[i].shift_y+this.ref_pixels[i].dshft_y*dpix)/this.pixel_y_ratio;
583
                    return {cap:cp, ele:el};
584
                }
585
            }
586
        } else {
587
            var cp = 360*px/this.im.width;
588
            var el = 360*py/this.im.height;
589
            return {cap:cp, ele:el};
590
        }
591
    }
592

    
593
    this.get_pos_xy = function(cap, ele) {                  // recherche des coordonnées pixel à partir d'un cap et d'une élévation.
594
        if (is_located) {
595
            var dcap = fmodulo(cap-this.ref_pixels[0].cap, 360);
596
            for (var i=0; i < this.ref_pixels.length; i++) {
597
                if (i == this.ref_pixels.length - 1 || dcap < fmodulo(this.ref_pixels[i+1].cap-this.ref_pixels[0].cap, 360)) {
598
                    var px = this.ref_pixels[i].x + this.ref_pixels[i].ratio_x*fmodulo(cap - this.ref_pixels[i].cap, 360);
599
                    var dpix = px-this.ref_pixels[i].x;
600
                    var py = this.pixel_y_ratio*ele - this.ref_pixels[i].shift_y - this.ref_pixels[i].dshft_y*dpix;
601
                    return {x:px, y:py};
602
                }
603
            }
604
        } else {
605
            var px = fmodulo(cap, 360)/360*this.im.width;
606
            var py = ele/360*this.im.height;
607
            return {x:px, y:py};
608
        }
609
    }
610
}
611

    
612
function reset_zooms () {
613
    for(i=0; i<zooms.length; i++) zooms[i].is_updated = false;
614
    zm.refresh();
615
}
616

    
617
function wheel_zoom (event) {
618
    var zshift = {x:0, y:0};
619
    if (event.pageX != undefined && event.pageX != undefined) {
620
        zshift.x = event.pageX-canvas.width/2-canvas_pos.x;
621
        zshift.y = event.pageY-canvas.height/2-canvas_pos.y;
622
    }
623
    event.preventDefault();
624
    if (event.wheelDelta < 0 && zoom_control.value < zoom_control.max) {
625
        zoom_control.value++;
626
        change_zoom(zshift.x, zshift.y);
627
    } else if (event.wheelDelta > 0 && zoom_control.value > zoom_control.min) {
628
        zoom_control.value--;
629
        change_zoom(zshift.x, zshift.y);
630
    }
631
}
632

    
633
function change_zoom(shx, shy) {
634
    var zoom_control = document.getElementById("zoom_ctrl");
635
    var v = zoom_control.value;
636

    
637
    prev_zm = zm;
638

    
639
    if (zooms[v]) {
640
        if (!zooms[v].is_updated) zooms[v].refresh();
641
    } else {
642
        zooms[v] = new tzoom(v);
643
    }
644

    
645
    if (zooms[v].is_updated) {
646
        if (shx == undefined || shy == undefined) {
647
            shx=0;
648
            shy=0;
649
        }
650
        zm = zooms[v];
651
        var px = (last.x+shx)*zm.im.width/prev_zm.im.width - shx;
652
        var py = (last.y+shy)*zm.im.height/prev_zm.im.height - shy;
653
        if (py < zm.im.height && py >= 0) {
654
            zoom = zm.value;
655
            tile = zm.tile;
656
            ntiles = zm.ntiles;
657
            putImage(px, py);
658
        } else {
659
            zm = prev_zm;
660
            zoom_control.value = zm.value;
661
        }
662
    }
663
}
664

    
665
function change_angle() {
666
    var elvtn_control = document.getElementById('elvtn_ctrl');
667
    var angle_control = document.getElementById('angle_ctrl');
668
    var resxy = zm.get_pos_xy(angle_control.value, elvtn_control.value);
669
    var pos_x = resxy.x;
670
    var pos_y = Math.floor(zm.im.height/2 - resxy.y);
671
    putImage(pos_x, pos_y);
672
}
673

    
674
function check_prox(x, y, r) {   //verification si un point de coordonnées x, y est bien dans un cercle de rayon r centré en X,Y.
675
    return Math.sqrt(x*x + y*y) < r;
676
}
677

    
678
function check_links(e) {
679
    var mouse_x = e.pageX-canvas_pos.x;
680
    var mouse_y = e.pageY-canvas_pos.y;
681
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
682
    var pos_y = last.y + mouse_y - canvas.height/2;
683
    for(var i = 0; i < zm.pt_list.length; i++) {
684
        if (is_located && zm.pt_list[i]['type'] == 'pano_point') {
685
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
686
                if (zm.pt_list[i]['lnk'] != '') window.location = zm.pt_list[i]['lnk'];
687
                break;
688
            }
689
        }
690
    }
691
}
692

    
693
function display_links(e) {
694
    var info = document.getElementById('info');
695
    var mouse_x = e.pageX-canvas_pos.x;
696
    var mouse_y = e.pageY-canvas_pos.y;
697
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
698
    var pos_y = last.y + mouse_y - canvas.height/2;
699
    //var cap = ((pos_x/zm.im.width)*360).toFixed(2);
700
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
701
    //var ele = ((zm.im.height/2 - pos_y)/zm.im.width)*360;
702
    info.innerHTML = 'élévation : '+res.ele.toFixed(2)+'<br/>cap : '+res.cap.toFixed(2);
703
    info.style.top = e.pageY+'px';
704
    info.style.left = e.pageX+'px';
705
    info.style.backgroundColor = '#FFC';
706
    info.style.display = 'block';
707
    canvas.style.cursor='crosshair';
708
    for(var i = 0; i < zm.pt_list.length; i++) {
709
        if (is_located || zm.pt_list[i]['type'] == 'ref_point') {
710
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
711
                info.innerHTML = zm.pt_list[i]['label'];
712
                if (zm.pt_list[i]['dist'] < 10) var dst = Math.round(zm.pt_list[i]['dist']*1000)+' m';
713
                else var dst = zm.pt_list[i]['dist'].toFixed(1)+' kms';
714
                info.innerHTML += '<br/> à ' + dst;
715
                info.style.backgroundColor = 'rgb('+point_colors[zm.pt_list[i]['type']]+')';
716
                canvas.style.cursor='auto';
717
                break;
718
            }
719
        }
720
    }
721
}
722

    
723
function hide_links() {
724
    canvas.removeEventListener( "mousemove", display_links, false);
725
    var info = document.getElementById('info');
726
    info.style.display = 'none';
727
}
728

    
729
function show_links() {
730
    canvas.addEventListener( "mousemove", display_links, false);
731
//    var info = document.getElementById('info');
732
//    info.style.display = 'block';
733
}
734

    
735
function hide_contextmenu() {
736
    document.getElementById('insert').style.display = 'none';
737
}
738

    
739
function manage_ref_points(e) {
740
    //event.preventDefault();
741
    //event.stopPropagation();
742
        var sel_pt = document.getElementById('sel_point');
743
    var do_insert = document.getElementById('do-insert');
744
        var do_delete = document.getElementById('do-delete');
745
        var do_cancel = document.getElementById('do-cancel');
746
        var show_cap = document.getElementById('show-cap');
747
        var insrt = document.getElementById('insert');
748

    
749
    var pos_x = nmodulo(last.x + e.pageX - canvas_pos.x - canvas.width/2, zm.im.width);
750
        var pos_y = last.y + e.pageY - canvas_pos.y - canvas.height/2;
751

    
752
        insrt.style.left = e.pageX+'px';
753
        insrt.style.top = e.pageY+'px';
754
        insrt.style.display = 'block';
755

    
756
        if (do_insert) {// true if there are ref points
757
                    for(var i = 0; i < zm.pt_list.length; i++) {
758
                            if (zm.pt_list[i]['type'] == 'ref_point') {
759
                                    if (check_prox(zm.pt_list[i]['xc']-pos_x,
760
                                                   zm.pt_list[i]['yc']-pos_y, 20)) {
761
                                            sel_pt.value = zm.pt_list[i]['label'];
762
                                    }
763
                            }
764
                    }
765
                do_delete.onclick = function() {delete_ref_point(insrt)};
766
                do_insert.onclick = function() {insert_ref_point(insrt, e.pageX-canvas_pos.x, e.pageY-canvas_pos.y)};
767
                show_cap.onclick = function() {
768
                        window.open('show_capline.php?title='+encodeURIComponent(btoa(title))+'&cap='+res.cap+'&org_lat='+pt_lat+'&org_lon='+pt_lon+'&dist=120000');
769
                };
770
        }
771

    
772
        do_cancel.onclick = hide_contextmenu;
773
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
774
    var pt_lat = document.getElementById('pos_lat').childNodes[0].nodeValue;
775
    var pt_lon = document.getElementById('pos_lon').childNodes[0].nodeValue;
776
    return false;
777
}
778

    
779
function insert_ref_point(el, x, y) {
780
        var label, posx, posy;
781
    el.style.display = 'none';
782
    for(var i = 0; i < zm.pt_list.length; i++) {
783
        label = zm.pt_list[i]['label'];
784
        if(label == document.getElementById('sel_point').value) {
785
            posx = nmodulo(last.x + x - canvas.width/2, zm.im.width)/zm.im.width;
786
            posy = 0.5 - (last.y + y - canvas.height/2)/zm.im.height;
787
            var pval = {x:posx, y:posy, cap:zm.pt_list[i]['cap'], ele:zm.pt_list[i]['ele'], label:label};
788
            ref_points[label] = pval;
789
            document.getElementById('res').innerHTML = '<h4>Dernier point entré</h4>';
790
            document.getElementById('res').innerHTML += '<p>reference["'+label+'"] = '+posx.toFixed(5)+','+posy.toFixed(5)+'</p>';
791
            reset_zooms();
792
             putImage(last.x, last.y);
793
            break;
794
        }
795
    }
796
        show_result();
797
        
798
        // Then push the modif
799
        var xhr = getXMLHttpRequest();
800
        xhr.open("POST", "ajax/add_reference.php", true);
801
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
802
        xhr.send("ref_point="+encodeURIComponent(label)
803
                 +"&panorama="+encodeURIComponent(get_base_name())
804
                 +"&x="+posx+"&y="+posy);
805
}
806

    
807
function show_result(clear_before) {
808
    var res = document.getElementById('res');
809
    var strg = '';
810
    for (var lbl in ref_points) {
811
        strg += '<li>reference["'+lbl+'"] = '+ref_points[lbl].x.toFixed(5)+','+ref_points[lbl].y.toFixed(5)+'</li>';
812
    }
813
    if (strg) strg = '<h3>Liste de tous les points de référence</h3>\n<ul>' + strg + '</ul>';
814
    if (clear_before) res.innerHTML = strg;
815
    else res.innerHTML += strg;
816
}
817

    
818
function delete_ref_point(el) {
819
        var ref_name = document.getElementById('sel_point').value;
820
    el.style.display = 'none';
821
    delete ref_points[ref_name];
822
    reset_zooms();
823
    putImage(last.x, last.y);
824
        show_result(true);
825
        
826
        // Then push the modif
827
        var xhr = getXMLHttpRequest();
828
        xhr.open("POST", "ajax/rm_reference.php", true);
829
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
830
        xhr.send("ref_point="+encodeURIComponent(ref_name)
831
                 +"&panorama="+encodeURIComponent(get_base_name()));
832
}
833

    
834
function clean_canvas_events(e) {
835
    canvas.removeEventListener('mousemove', stickImage, false);
836
    document.getElementById('info').style.display = 'none';
837
    speed.x = 0;
838
    speed.y = 0;
839
}
840

    
841
canvas_set_size = function() {
842
    canvas.style.border = border_width+"px solid red";
843
    canvas.width = window.innerWidth-2*border_width;
844
    canvas.height = window.innerHeight-2*border_width;
845
    canvas_pos.x = canvas.offsetLeft+border_width;
846
    canvas_pos.y = canvas.offsetTop+border_width;
847
}
848

    
849
canvas_resize = function() {
850
    canvas_set_size();
851
    putImage(last.x, last.y);
852
}
853

    
854
function paramIn(e) {
855
    e = e || window.event;
856
    var relatedTarget = e.relatedTarget || e.fromElement;
857

    
858
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
859
        relatedTarget = relatedTarget.parentNode;
860
    }
861

    
862
    if (relatedTarget != adding && relatedTarget != localisation) {
863
        document.removeEventListener('keydown', keys, false);
864
    }
865
}
866

    
867
function paramOut(e) {
868

    
869
    e = e || window.event;
870
    var relatedTarget = e.relatedTarget || e.toElement;
871

    
872
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
873
        relatedTarget = relatedTarget.parentNode;
874
    }
875

    
876
    if (relatedTarget != adding && relatedTarget != localisation) {
877
            document.addEventListener('keydown', keys, false);
878
    }
879

    
880
}
881

    
882

    
883
function load_pano() {
884
        localisation = document.getElementById("locadraw");
885
    adding = document.getElementById("adding");
886
    canvas = document.getElementById("mon-canvas");
887
    cntext = canvas.getContext("2d");
888
    canvas_set_size();
889
    canvas.addEventListener("click", check_links, false);
890
    //canvas.addEventListener("oncontextmenu", manage_ref_points, false);
891
    canvas.oncontextmenu = manage_ref_points;
892
    canvas.addEventListener("mouseout" , clean_canvas_events, false);
893
    show_links();
894

    
895
    var max_zoom = zooms.length - 1;
896
    zoom_control = document.getElementById("zoom_ctrl");
897
    zoom_control.onchange = change_zoom;
898
    zoom_control.max = max_zoom;
899
    if (to_zoom > max_zoom) to_zoom = Math.floor(max_zoom/2);
900
    zm = zooms[to_zoom];
901
    zoom_control.value = to_zoom;
902
    zm.refresh();
903

    
904
    zoom = zm.value;
905
    tile = zm.tile;
906
    ntiles = zm.ntiles;
907

    
908
    angle_control = document.getElementById("angle_ctrl");
909
    angle_control.value = to_cap;
910
    angle_control.onchange = change_angle;
911
    angle_control.onclick = change_angle;
912
    elvtn_control = document.getElementById("elvtn_ctrl");
913
    elvtn_control.value = to_ele;
914
    elvtn_control.onchange = change_angle;
915
    elvtn_control.onclick = change_angle;
916

    
917
    change_angle();
918
    loca_temp = document.getElementById("loca_show");
919
    if (loca_temp) {
920
        loca_temp.onclick = showLoca;
921
        loca_temp = document.getElementById("loca_hide");
922
        loca_temp.onclick = hideLoca;
923
        loca_temp = document.getElementById("loca_button");
924
        loca_temp.onclick = localate_point;
925
        loca_erase = document.getElementById("loca_erase");
926
        loca_erase.onclick = erase_point;
927
        localisation.addEventListener('mouseover',paramIn,false);
928
        localisation.addEventListener('mouseout',paramOut,false);
929
    }
930
    canvas.addEventListener('mousedown', onImageClick, false);
931
    document.addEventListener('keydown', keys, false);
932
    canvas.addEventListener('mousewheel', wheel_zoom, false);
933
    window.onresize = canvas_resize;
934
    if (adding) {
935
        document.getElementById("paramFormHide").onclick = hideForm;
936
        document.getElementById("paramFormShow").onclick = showForm;
937
        adding.addEventListener('mouseover', paramIn, false);
938
        adding.addEventListener('mouseout', paramOut, false);
939
    }
940
};