Projet

Général

Profil

Paste
Télécharger (29,8 ko) Statistiques
| Branche: | Révision:

root / js / pano.js @ 72ecbd21

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 = true;
11

    
12
var pt_alt;
13
var pt_lat;
14
var pt_lon;
15

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

    
29
var last  = {x:0,y:0};
30
var shift = {x:0,y:0};
31
var mouse = {x:0,y:0};
32
var speed = {x:0,y:0};
33
var canvas_pos = {x:0,y:0};
34
var tmt;
35
var is_located = false;
36
var point_colors = {'pano_point' : '255,128,128',
37
                    'ref_point'  : '128,128,255',
38
                    'loc_point'  : '128,255,128',
39
                    'temporary'  : '255,255,128',
40
                    'unlocated'  : '255,255,255'};
41
var test = {x:0, y:0, i:100};
42

    
43

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

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

    
52
function distort_canvas(p, x, y) {
53
    if (p == 0) distort = 0;
54
    else {
55
        cntext.save();
56
        distort++;
57
        cntext.clearRect(0, 0, canvas.width, 2*canvas.height);
58
        var ratio = (canvas.width-2*distort)/canvas.width;
59
        var shift = canvas.height/2*(1-ratio);
60
        cntext.scale(1, ratio);
61
        if (p == 1) cntext.translate(0, 0);
62
        else if (p == -1) cntext.translate(0, 0);
63
        draw_image(x, y);
64
        cntext.restore();
65
        document.getElementById('res').innerHTML = 'distort : ' + distort + ' shift ' + shift + ' ratio : ' + ratio + '<br/>';
66
    }
67
}
68

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

    
74
    cntext.clearRect(0, 0, canvas.width, canvas.height);
75
    cntext.fillStyle = "rgba(128,128,128,0.8)";
76
    
77
    if (canvas.height > zm.im.height) {
78
        var fy = Math.floor((oy+canvas.height/2-zm.im.height/2)/(tile.height*zm.ntiles.y))*zm.ntiles.y;
79
        if (fy < 0) fy = 0; 
80
        var ly = fy + zm.ntiles.y;
81
    } else {
82
        var fy = Math.floor(oy/tile.height);
83
        var ly = Math.floor((oy+canvas.height+tile.height-1)/tile.height+1);
84
        if (fy < 0) fy = 0; 
85
        if (ly > zm.ntiles.y) ly = zm.ntiles.y; 
86
    }
87

    
88
    for (var j=fy; j<ly; j++) {
89
        var delta_y = (Math.floor(j/zm.ntiles.y) - Math.floor(fy/zm.ntiles.y)) * (tile.height - zm.last_tile.height);
90
        var dy = j*tile.height - oy - delta_y;
91
        var ny = j%ntiles.y;
92
        var wy = zm.tile.width;
93
        if (ny == zm.ntiles.y - 1) wy = zm.last_tile.height;
94

    
95
        var cpx = 0;
96
        var i = 0;
97
        var Nx = zm.ntiles.x;
98
        while (cpx < ox+canvas.width) {
99
            var cur_width = zm.tile.width;
100
            if (i%Nx == zm.ntiles.x-1) cur_width = zm.last_tile.width;
101
            if (cpx >= ox-cur_width) {
102
                var nx = i%Nx;
103
                var idx = nx+'-'+ny+'-'+ref_vals.zoom;
104
                if (imageObj[idx] && imageObj[idx].complete) {
105
                    draw_tile(idx, cpx-ox, dy); // l'image est déja en mémoire, on force le dessin sans attendre.
106
                } else {
107
                    var fname = get_file_name(nx, ny, ref_vals.zoom);
108
                    imageObj[idx] = new Image();
109
                    imageObj[idx].src = fname;
110
                    var ts = zm.get_tile_size(nx, ny);
111
                    cntext.fillRect(cpx-ox, dy, ts.width, ts.height);
112
                    imageObj[idx].addEventListener('load', (function(ref, idx, dx, dy, ox, oy, ts) {
113
                        return function() {        // closure nécéssaire pour gestion assynchronisme !!!
114
                            draw_tile_del(ref, idx, dx, dy, ox, oy, ts.width, ts.height);
115
                        };
116
                    })(ref_vals, idx, cpx-ox, dy, ox, oy, ts), false);
117
                }
118
//                load_image(zoom, nx, ny, shx, shy, cpx-ox, dy, ox, oy);
119
            }
120
            cpx += cur_width;
121
            i++;
122
        }
123
    }
124
    drawDecorations(ox, oy);
125
}
126

    
127
function draw_tile_del(ref, idx, tx, ty, ox, oy, twidth, theight) {
128
    if (ref.zoom == zoom && ref.x == last.x && ref.y == last.y) {
129
        draw_tile(idx, tx, ty);
130
        drawDecorations(ox, oy, tx, ty, twidth, theight);
131
    }
132
}
133

    
134
function draw_tile(idx, ox, oy) {
135
    var img = imageObj[idx];
136
    cntext.drawImage(img, ox, oy);
137
}
138

    
139
function drawDecorations(ox, oy, tx, ty, twidth, theight) {
140
    if (twidth) {
141
        cntext.save();
142
        cntext.beginPath();
143
        cntext.rect(tx, ty, twidth, theight);
144
        cntext.clip();
145
    } 
146
    var wgrd = zm.im.width/360;
147
    var od = ((ox+canvas.width/2)/wgrd)%360;
148
    var el = (zm.im.height/2 - (oy+canvas.height/2))/wgrd;
149
    cntext.fillStyle = "rgba(0,128,128,0.9)";
150
    cntext.strokeStyle = "rgb(255,255,255)";
151
    cntext.lineWidth = 1;
152
    cntext.fillRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
153
    cntext.strokeRect(canvas.width/2-5, canvas.height/2-5, 10, 10);
154
    for(var i = 0; i < zm.pt_list.length; i++) {
155
        if (zm.pt_list[i]['type'] != 'unlocated') {
156
            cntext.fillStyle = 'rgba('+point_colors[zm.pt_list[i]['type']]+',0.5)';
157
            var cx = nmodulo(zm.pt_list[i]['xc'] - ox, zm.im.width);
158
            var cy = zm.pt_list[i]['yc'] - oy;
159
            cntext.beginPath();
160
            cntext.arc(cx, cy, 20, 0, 2*Math.PI, true);
161
            cntext.fill();
162
        }
163
    }
164

    
165
    //cntext.font = "20pt Arial";
166
    //cntext.fillRect(0, 0, 200, 20);
167
    //cntext.fillStyle = "rgb(255,0,0)";
168
    //cntext.fillText(od.toFixed(2), 5, 20);
169
    //for (i=0; i<canvas.width/wgrd; i++) {
170
        //cntext.strokeRect(i*wgrd, 0, wgrd, 20);
171
    //}
172
    if (twidth) {
173
        cntext.restore();
174
    }
175
    
176
}
177

    
178
function insert_drawn_point(lat, lon, alt) {
179
    var rt = 6371;  // Rayon de la terre
180
    var alt1 = pt_alt;
181
    var lat1 = pt_lat*Math.PI/180;
182
    var lon1 = pt_lon*Math.PI/180;
183
    var alt2 = alt;
184
    var lat2 = lat*Math.PI/180;
185
    var lon2 = lon*Math.PI/180;
186
    
187
    var dLat = lat2-lat1;
188
    var dLon = lon2-lon1; 
189
   
190
    var a = Math.sin(dLat/2)*Math.sin(dLat/2) + Math.sin(dLon/2)*Math.sin(dLon/2)*Math.cos(lat1)*Math.cos(lat2);  // 
191
    var angle = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
192
    var d = angle*rt;                    // distance du point en Kms
193
   
194
    var y = Math.sin(dLon) * Math.cos(lat2);
195
    var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
196
    var cap = Math.atan2(y,x);                 // cap pour atteindre le point en radians
197
    var e = Math.atan2((alt2 - alt1)/1000 - d*d/(2*rt),d);  // angle de l'élévation en radians
198
    
199
    return {d:d, cap:cap*180/Math.PI, ele:e*180/Math.PI};   // les résultats sont en degrés
200
}
201

    
202
function localate_point() {
203
    var lat = document.getElementById("loca_latitude").value;
204
    var lon = document.getElementById("loca_longitude").value;
205
    var alt = document.getElementById("loca_altitude").value;
206
    if (lat == '' || isNaN(lat) || lat <= -90 || lat > 90) {
207
        alert("La latitude "+lat+"n'est pas correcte");
208
        return;
209
    }
210
    if (lat == '' || isNaN(lon) || lon <= -180 || lon > 180) {
211
        alert("La longitude "+lon+"n'est pas correcte");
212
        return;
213
    }
214
    if (lat == '' || isNaN(alt) || alt < -400 || alt > 10000000) {
215
        alert("l'altitude "+alt+"n'est pas correcte");
216
        return;
217
    }
218
    var opt_ced = new Array();
219
    opt_dce = insert_drawn_point(lat, lon, alt);
220
    display_temp(opt_dce.d, opt_dce.cap, opt_dce.ele);
221
}
222

    
223
function display_temp(d,cap,ele) {  
224
    point_list[point_list.length] = new Array("point temporaire", d,cap,ele, "temporary");
225
    reset_zooms();
226
    putImage(last.x, last.y);
227
}
228

    
229
function arrayUnset(array, value){
230
    array.splice(array.indexOf(value), 1);
231
}
232

    
233
function erase_point() {        
234
        for (var i=0; i<point_list.length; i++) {
235
                if(point_list[i][0] == "point temporaire"){
236
                        arrayUnset(point_list,point_list[i]);
237
                        loop = erase_point();
238
                }        
239
        }        
240
        reset_zooms();
241
    putImage(last.x, last.y);   
242
}
243

    
244
function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position
245
    var prm = [z, x, y];
246
    var fname = img_prefix;
247
    for (var i = 0; i < prm.length; i++) {
248
        fname += '_';
249
        if (prm[i] < 10) fname += '00';
250
        else if (prm[i] < 100) fname += '0';
251
        fname += prm[i];
252
    }
253
    fname += '.jpg';
254
    return fname;
255
}
256

    
257
function keys(key) {
258
        
259
    hide_links();
260
    evt = key || event;
261
    //evt.preventDefault();
262
    //evt.stopPropagation();
263
    if (!key) {
264
        key = window.event;
265
        key.which = key.keyCode;
266
    }
267
//    alert(key);
268
//    if (!evt.shiftKey) return;
269
    switch (key.which) {
270
    /*case 66: // b
271
        alert(key.pageX);
272
        test.x=tile.width*(ntiles.x-3);
273
        test.y=0;
274
        putImage(test.x, test.y);
275
        return;
276
    case 67: // c
277
        test.x=0;
278
        test.y=tile.height*(ntiles.y-3);
279
        putImage(test.x, test.y);
280
        return;*/
281
    case 36: // home
282
        putImage(0, zm.im.height/2);
283
        return;
284
    case 35: // end
285
        putImage(last.x+zm.im.width/2, last.y);
286
        return;
287
    case 39: // left
288
        putImage(last.x+40, last.y);
289
        return;
290
    case 40: // up
291
        putImage(last.x, last.y+20);
292
        return;
293
    case 37: // right
294
        putImage(last.x-40, last.y);
295
        return;
296
    case 38: // down
297
        putImage(last.x, last.y-20);
298
        return;
299
    case 33: // pageup
300
        zoom_control.value--;
301
        change_zoom()
302
        return;
303
    case 34: // pagedown
304
        zoom_control.value++;
305
        change_zoom()
306
        return;
307
    default:
308
//        alert(key.which)
309
        return;
310
    }
311
}
312

    
313
function onImageClick(e) {
314
    hide_contextmenu();
315
    shift.x = last.x;
316
    shift.y = last.y;
317
    speed.x = 0;
318
    speed.y = 0;
319
    mouse.x = e.pageX;
320
    mouse.y = e.pageY;
321
    clearTimeout(tmt);  //arrêt de l'éffet eventuel d'amorti en cours.
322
    canvas.addEventListener('mousemove', stickImage, false);
323
    canvas.addEventListener('mouseup', launchImage, false);
324
    //canvas.addEventListener('mouseout', launchImage, false);
325
    canvas.style.cursor='move';
326
    //document.onmousemove = stickImage;
327
    document.onmouseup = launchImage;
328
    hide_links();
329
}
330

    
331

    
332
function stickImage(e) {
333
    var xs = mouse.x - e.pageX + shift.x;
334
    var ys = mouse.y - e.pageY + shift.y;
335
    speed.x = xs - last.x;  //mémorisation des vitesses horizontales
336
    speed.y = ys - last.y;  //et verticales lors de ce déplacement
337
    putImage(xs, ys);
338
}
339

    
340
function launchImage(e) {
341
    distort_canvas(0);
342
    canvas.removeEventListener('mousemove', stickImage, false);
343
    //document.onmousemove = null;
344
    shift.x = e.pageX - mouse.x + shift.x;
345
    shift.y = e.pageY - mouse.y + shift.y;
346
    tmt = setTimeout(inertialImage, 100);
347
}
348

    
349
function putImage(x, y) { // est destiné à permettre l'effet d'amortissement par la mémorisation de la position courante.
350
    if (!zm.is_updated) return; 
351
    if (x >= zm.im.width) {   // rebouclage horizontal
352
        shift.x -= zm.im.width;
353
        x -= zm.im.width;
354
    } else if (x < 0) {
355
        shift.x += zm.im.width;
356
        x += zm.im.width;
357
    }
358
    if (y >= zm.im.height) {   // pas de rebouclage vertical mais blocage
359
        //distort_canvas(1, x, y);
360
        shift.y = zm.im.height-1;
361
        y = zm.im.height-1;
362
    } else if (y < 0) {
363
        //distort_canvas(-1, x, y);
364
        shift.y = 0;
365
        y = 0;
366
    }
367

    
368
    last.x = x;
369
    last.y = y;
370
    draw_image(x, y);
371
}
372

    
373
function inertialImage() {
374
    speed.x *= 0.9;
375
    speed.y *= 0.9;
376
    if (Math.abs(speed.x) > 2 || Math.abs(speed.y) > 2) {
377
        putImage(last.x+speed.x, last.y+speed.y);
378
        tmt = setTimeout(inertialImage, 100);
379
    } else {
380
        show_links();
381
    }
382
}
383

    
384
function tri_ref_points(v1, v2) {
385
    return v1['x'] - v2['x'];
386
}
387

    
388

    
389

    
390
function tzoom(zv) {
391
    this.value = zv;
392
    this.ntiles = {x:0,y:0};
393
    this.tile = {width:0,height:0};
394
    this.last_tile = {width:0,height:0};
395
    this.max_tile = {width:0,height:0};
396
    this.im = {width:0,height:0};
397
    this.is_updated = false;
398

    
399
    this.refresh = function() {
400
        this.im.visible_width = this.tile.width*(this.ntiles.x-1)+this.last_tile.width;
401
        this.is_updated = true;
402

    
403
        this.im.width = this.im.visible_width;
404
        this.im.height = this.tile.height*(this.ntiles.y-1)+this.last_tile.height;
405
        if (this.last_tile.width > this.tile.width) this.max_tile.width = this.im.last_tile.width;
406
        else this.max_tile.width = this.tile.width;
407
        if (this.last_tile.height > this.tile.height) this.max_tile.height = this.im.last_tile.height;
408
        else this.max_tile.height = this.tile.height;
409

    
410
        var ord_pts = new Array();
411
        i=0;
412
        for(var label in ref_points) {
413
            ord_pts[i++] = ref_points[label]
414
        }
415
        ord_pts = ord_pts.sort(tri_ref_points);
416
        is_located = i > 1 || image_loop && i > 0;
417

    
418
        var alpha_domain = {start:0, end:360}; 
419
        this.pixel_y_ratio = this.im.width/360;
420
        if (is_located) {
421
            this.ref_pixels = new Array;
422
            this.ref_pixels[0] = new Array();    // Attention il faut compter un intervalle de plus !
423
            for (var i=0; i < ord_pts.length; i++) { // premier parcours pour les paramètres cap/x
424
                this.ref_pixels[i+1] = new Array();
425
                this.ref_pixels[i+1].x = Math.floor(ord_pts[i].x*this.im.width);
426
                this.ref_pixels[i+1].cap = fmodulo(ord_pts[i].cap, 360);
427
                if (i != ord_pts.length-1) {
428
                    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;
429
                }
430
            }
431
            if (image_loop == true) {
432
                var dpix = this.im.width;
433
                var dangle = 360;
434
                if (ord_pts.length > 1) {
435
                    dpix = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
436
                    dangle = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[this.ref_pixels.length-1].cap, 360);
437
                }
438
                this.ref_pixels[0].ratio_x = dpix/dangle;
439
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[0].ratio_x;
440
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
441
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[ord_pts.length].cap + dpix / this.ref_pixels[0].ratio_x, 360);
442
            } else {
443
                this.ref_pixels[0].ratio_x = this.ref_pixels[1].ratio_x;
444
                this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[ord_pts.length-1].ratio_x;
445
                this.ref_pixels[0].cap = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[1].x / this.ref_pixels[1].ratio_x, 360);
446
                alpha_domain.start = this.ref_pixels[0].cap;
447
                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);
448
                this.pixel_y_ratio = this.im.width/fmodulo(alpha_domain.end-alpha_domain.start, 360);
449
            }
450
            this.ref_pixels[0].x = 0;
451

    
452
            for (var i=0; i < ord_pts.length; i++) { // second parcours pour les paramètres elevation/y
453
                this.ref_pixels[i+1].shift_y = Math.floor(this.pixel_y_ratio*ord_pts[i].ele - ord_pts[i].y*this.im.height);
454
                if (i != ord_pts.length-1) {
455
                    var next_shift = Math.floor(this.pixel_y_ratio*ord_pts[i+1].ele - ord_pts[i+1].y*this.im.height);
456
                    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);
457
                }
458
            }
459

    
460
            if (image_loop == true) {
461
                var dpix  = this.im.width;
462
                var delt = 0;
463
                if (ord_pts.length > 1) {
464
                    dpix  = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
465
                    delt = this.ref_pixels[this.ref_pixels.length-1].shift_y - this.ref_pixels[1].shift_y;
466
                }
467
                this.ref_pixels[0].dshft_y = delt/dpix;
468
                this.ref_pixels[ord_pts.length].dshft_y = this.ref_pixels[0].dshft_y;
469
                dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
470
                this.ref_pixels[0].shift_y = this.ref_pixels[ord_pts.length].shift_y - dpix*this.ref_pixels[0].dshft_y;
471
            } else {
472
                this.ref_pixels[0].shift_y = this.ref_pixels[1].shift_y;
473
                this.ref_pixels[0].dshft_y = 0;
474
                this.ref_pixels[ord_pts.length].dshft_y = 0;
475
            }
476

    
477
            if (debug_mode) {
478
                var res = document.getElementById('res');
479
                res.innerHTML = 'liste des '+this.ref_pixels.length+' valeurs de correction (image = '+this.im.width+'x'+this.im.height+') zoom = '+this.value+':<br/>';
480
                for (var i=0; i < this.ref_pixels.length; i++) { // pour le debug
481
                    res.innerHTML += '<p>point '+i+' :</p><ul>';
482
                    for (var key in this.ref_pixels[i]) { // pour le debug
483
                        res.innerHTML += '<li>'+key + '['+i+'] = '+this.ref_pixels[i][key]+'</li>';
484
                    }
485
                    if (i != this.ref_pixels.length-1) {
486
                        var tx0 = this.ref_pixels[i+1].x-1;
487
                        //var ty0 = this.ref_pixels[i+1].shift_y;
488
                        var ty0 = 0;
489
                    } else {
490
                        var tx0 = this.im.width-1;
491
                        var ty0 = 0;
492
                    }
493
                    res.innerHTML += '</ul><p>test sur : '+tx0+','+ty0+'</p>';
494
                    var tst = this.get_cap_ele(tx0, ty0);
495
                    res.innerHTML += '<p>cap:'+tst.cap+', shift:'+tst.ele+'</p>';
496
                    var tst2 = this.get_pos_xy(tst.cap, tst.ele);
497
                    res.innerHTML += '</ul><p>x:'+tst2.x+', y:'+tst2.y+'</p>';
498
                }
499
            }
500
        }
501

    
502
        this.pt_list = new Array();
503
        for (var i=0; i<point_list.length; i++) {
504
            var lbl = point_list[i][0];
505
            var dst = point_list[i][1];
506
            var cap = point_list[i][2];
507
            var ele = point_list[i][3];
508
            var lnk = point_list[i][4];
509
            var typ = 'unlocated';
510
            var rxy = this.get_pos_xy(cap, ele);
511
            var is_visible = fmodulo(cap - alpha_domain.start, 360) <= fmodulo(alpha_domain.end - alpha_domain.start -0.0001, 360)+0.0001 && is_located;
512

    
513
            this.pt_list[i] = new Array();
514
            if (ref_points[lbl] != undefined) {
515
                typ = 'ref_point';
516
                if (!is_located) rxy = {x:ref_points[lbl].x*this.im.width, y:ref_points[lbl].y*this.im.height}
517
            } else if(lnk == '' && is_visible && lbl != 'point temporaire') {
518
                typ = 'loc_point';
519
            }else if(is_visible && lbl =='point temporaire') {
520
            typ = 'temporary';
521
            
522
            } else if(is_visible) {
523
                typ = 'pano_point';
524
                lnk += '&to_zoom='+this.value;
525
            } 
526
            this.pt_list[i]['type'] = typ;
527
            this.pt_list[i]['cap'] = cap;
528
            this.pt_list[i]['ele'] = ele;
529
            this.pt_list[i]['dist'] = dst;
530
            this.pt_list[i]['label'] = lbl;
531
            this.pt_list[i]['lnk'] = lnk;
532
            this.pt_list[i]['xc'] = rxy.x;
533
            this.pt_list[i]['yc'] = Math.floor(this.im.height/2 - rxy.y);
534
        }
535
    }
536
    
537
    this.get_tile_size = function(nx, ny) {
538
        var res = {width:0, height:0};
539
        if (nx == this.ntiles.x-1) res.width = this.last_tile.width;
540
        else res.width = this.tile.width;
541
        if (ny == this.ntiles.y-1) res.height = this.last_tile.height;
542
        else res.height = this.tile.height;
543
        return res;
544
    }
545
    
546
    this.get_cap_ele = function(px, py) {               // recherche d'un cap et d'une élévation à partir d'un pixel X,Y.
547
        if (is_located) {
548
            for (var i=0; i < this.ref_pixels.length; i++) {
549
                if (i == this.ref_pixels.length - 1 || px < this.ref_pixels[i+1].x) {
550
                    var dpix = px-this.ref_pixels[i].x;
551
                    var cp = fmodulo(this.ref_pixels[i].cap + dpix/this.ref_pixels[i].ratio_x, 360);
552
                    var el = (py+this.ref_pixels[i].shift_y+this.ref_pixels[i].dshft_y*dpix)/this.pixel_y_ratio;
553
                    return {cap:cp, ele:el};
554
                }
555
            }
556
        } else {
557
            var cp = 360*px/this.im.width;
558
            var el = 360*py/this.im.height;
559
            return {cap:cp, ele:el};
560
        }
561
    }
562
    
563
    this.get_pos_xy = function(cap, ele) {                  // recherche des coordonnées pixel à partir d'un cap et d'une élévation.
564
        if (is_located) {
565
            var dcap = fmodulo(cap-this.ref_pixels[0].cap, 360);
566
            for (var i=0; i < this.ref_pixels.length; i++) {
567
                if (i == this.ref_pixels.length - 1 || dcap < fmodulo(this.ref_pixels[i+1].cap-this.ref_pixels[0].cap, 360)) {
568
                    var px = this.ref_pixels[i].x + this.ref_pixels[i].ratio_x*fmodulo(cap - this.ref_pixels[i].cap, 360);
569
                    var dpix = px-this.ref_pixels[i].x;
570
                    var py = this.pixel_y_ratio*ele - this.ref_pixels[i].shift_y - this.ref_pixels[i].dshft_y*dpix;
571
                    return {x:px, y:py};
572
                }
573
            }
574
        } else {
575
            var px = fmodulo(cap, 360)/360*this.im.width;
576
            var py = ele/360*this.im.height;
577
            return {x:px, y:py};
578
        }
579
    }
580
}
581

    
582
function reset_zooms () {
583
    for(i=0; i<zooms.length; i++) zooms[i].is_updated = false;
584
    zm.refresh();
585
}
586

    
587
function wheel_zoom (event) {
588
    var zshift = {x:0, y:0};
589
    if (event.pageX != undefined && event.pageX != undefined) {
590
        zshift.x = event.pageX-canvas.width/2-canvas_pos.x;
591
        zshift.y = event.pageY-canvas.height/2-canvas_pos.y;
592
    }
593
    event.preventDefault();
594
    if (event.wheelDelta < 0 && zoom_control.value < zoom_control.max) {
595
        zoom_control.value++;
596
        change_zoom(zshift.x, zshift.y);
597
    } else if (event.wheelDelta > 0 && zoom_control.value > zoom_control.min) {
598
        zoom_control.value--; 
599
        change_zoom(zshift.x, zshift.y);
600
    }
601
}
602

    
603
function change_zoom(shx, shy) {
604
    var zoom_control = document.getElementById("zoom_ctrl");
605
    var v = zoom_control.value;
606

    
607
    prev_zm = zm;
608

    
609
    if (zooms[v]) {
610
        if (!zooms[v].is_updated) zooms[v].refresh();
611
    } else {
612
        zooms[v] = new tzoom(v);
613
    }
614

    
615
    if (zooms[v].is_updated) {
616
        if (shx == undefined || shy == undefined) {
617
            shx=0;
618
            shy=0;
619
        }
620
        zm = zooms[v];
621
        var px = (last.x+shx)*zm.im.width/prev_zm.im.width - shx;
622
        var py = (last.y+shy)*zm.im.height/prev_zm.im.height - shy;
623
        if (py < zm.im.height && py >= 0) {
624
            zoom = zm.value;
625
            tile = zm.tile;
626
            ntiles = zm.ntiles;
627
            putImage(px, py);
628
        } else {
629
            zm = prev_zm;
630
            zoom_control.value = zm.value;
631
        }
632
    }
633
}
634

    
635
function change_angle() {
636
    var elvtn_control = document.getElementById('elvtn_ctrl');
637
    var angle_control = document.getElementById('angle_ctrl');
638
    var resxy = zm.get_pos_xy(angle_control.value, elvtn_control.value);
639
    var pos_x = resxy.x;
640
    var pos_y = Math.floor(zm.im.height/2 - resxy.y);
641
    putImage(pos_x, pos_y);
642
}
643

    
644
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. 
645
    return Math.sqrt(x*x + y*y) < r;
646
}
647

    
648
function check_links(e) {
649
    var mouse_x = e.pageX-canvas_pos.x;
650
    var mouse_y = e.pageY-canvas_pos.y;
651
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
652
    var pos_y = last.y + mouse_y - canvas.height/2;
653
    for(var i = 0; i < zm.pt_list.length; i++) {
654
        if (is_located && zm.pt_list[i]['type'] == 'pano_point') {
655
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
656
                if (zm.pt_list[i]['lnk'] != '') window.location = zm.pt_list[i]['lnk'];
657
                break;
658
            }
659
        }
660
    }
661
}
662

    
663
function display_links(e) {
664
    var info = document.getElementById('info');
665
    var mouse_x = e.pageX-canvas_pos.x;
666
    var mouse_y = e.pageY-canvas_pos.y;
667
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
668
    var pos_y = last.y + mouse_y - canvas.height/2;
669
    //var cap = ((pos_x/zm.im.width)*360).toFixed(2);
670
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
671
    //var ele = ((zm.im.height/2 - pos_y)/zm.im.width)*360;
672
    info.innerHTML = 'élévation : '+res.ele.toFixed(2)+'<br/>cap : '+res.cap.toFixed(2);
673
    info.style.top = e.pageY+'px';
674
    info.style.left = e.pageX+'px';
675
    info.style.backgroundColor = '#FFC';
676
    info.style.display = 'block';
677
    canvas.style.cursor='crosshair';
678
    for(var i = 0; i < zm.pt_list.length; i++) {
679
        if (is_located || zm.pt_list[i]['type'] == 'ref_point') {
680
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
681
                info.innerHTML = zm.pt_list[i]['label'];
682
                if (zm.pt_list[i]['dist'] < 10) var dst = Math.round(zm.pt_list[i]['dist']*1000)+' m';
683
                else var dst = zm.pt_list[i]['dist'].toFixed(1)+' kms';
684
                info.innerHTML += '<br/> à ' + dst;
685
                info.style.backgroundColor = 'rgb('+point_colors[zm.pt_list[i]['type']]+')';
686
                canvas.style.cursor='auto';
687
                break;
688
            }
689
        }
690
    }
691
}
692

    
693
function hide_links() {
694
    canvas.removeEventListener( "mousemove", display_links, false);
695
    var info = document.getElementById('info');
696
    info.style.display = 'none';
697
}
698

    
699
function show_links() {
700
    canvas.addEventListener( "mousemove", display_links, false);
701
//    var info = document.getElementById('info');
702
//    info.style.display = 'block';
703
}
704

    
705
function hide_contextmenu() {
706
    document.getElementById('insert').style.display = 'none';
707
}
708

    
709
function manage_ref_points(e) {
710
    //event.preventDefault();
711
    //event.stopPropagation();
712
    var insrt = document.getElementById('insert');
713
    document.getElementById('do-cancel').onclick = hide_contextmenu;
714
    insrt.style.left = e.pageX+'px';
715
    insrt.style.top = e.pageY+'px';
716
    insrt.style.display = 'block';
717
    var sel_pt = document.getElementById('sel_point');
718
    var do_insert = document.getElementById('do-insert');
719
    var do_delete = document.getElementById('do-delete');
720
    var show_cap = document.getElementById('show-cap');
721
    var pos_x = nmodulo(last.x + e.pageX - canvas_pos.x - canvas.width/2, zm.im.width);
722
    var pos_y = last.y + e.pageY - canvas_pos.y - canvas.height/2;
723
    for(var i = 0; i < zm.pt_list.length; i++) {
724
        if (zm.pt_list[i]['type'] == 'ref_point') {
725
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
726
                sel_pt.value = zm.pt_list[i]['label'];
727
            }
728
        }
729
    }
730
    do_delete.onclick = function() {delete_ref_point(insrt)};
731
    do_insert.onclick = function() {insert_ref_point(insrt, e.pageX-canvas_pos.x, e.pageY-canvas_pos.y)};
732
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
733
    show_cap.onclick = function() {window.open('show_capline.php?title='+encodeURIComponent(title)+'&cap='+res.cap+'&org_lat='+pt_lat+'&org_lon='+pt_lon)};
734
    return false;
735
}
736

    
737
function insert_ref_point(el, x, y) {
738
    var label;
739
    el.style.display = 'none';
740
    for(var i = 0; i < zm.pt_list.length; i++) {
741
        label = zm.pt_list[i]['label'];
742
        if(label == document.getElementById('sel_point').value) {
743
            var posx = nmodulo(last.x + x - canvas.width/2, zm.im.width)/zm.im.width;
744
            var posy = 0.5 - (last.y + y - canvas.height/2)/zm.im.height;
745
            var pval = {x:posx, y:posy, cap:zm.pt_list[i]['cap'], ele:zm.pt_list[i]['ele'], label:label};
746
            ref_points[label] = pval;
747
            document.getElementById('res').innerHTML = '<h4>Dernier point entré</h4>';
748
            document.getElementById('res').innerHTML += '<p>reference["'+label+'"] = '+posx.toFixed(5)+','+posy.toFixed(5)+'</p>';
749
            reset_zooms();
750
             putImage(last.x, last.y);
751
            break;
752
        }
753
    }
754
    show_result();
755
}
756

    
757
function show_result(clear_before) {
758
    var res = document.getElementById('res');
759
    var strg = '';
760
    for (var lbl in ref_points) {
761
        strg += '<li>reference["'+lbl+'"] = '+ref_points[lbl].x.toFixed(5)+','+ref_points[lbl].y.toFixed(5)+'</li>';
762
    }
763
    if (strg) strg = '<h3>Liste de tous les points de référence</h3>\n<ul>' + strg + '</ul>';
764
    if (clear_before) res.innerHTML = strg;
765
    else res.innerHTML += strg;
766
}
767

    
768
function delete_ref_point(el) {
769
    el.style.display = 'none';
770
    delete ref_points[document.getElementById('sel_point').value];
771
    reset_zooms();
772
    putImage(last.x, last.y);
773
    show_result(true);
774
}
775

    
776
function clean_canvas_events(e) {
777
    canvas.removeEventListener('mousemove', stickImage, false);
778
    document.getElementById('info').style.display = 'none';
779
    speed.x = 0;
780
    speed.y = 0;
781
}
782

    
783
canvas_set_size = function() {
784
    canvas.style.border = border_width+"px solid red";
785
    canvas.width = window.innerWidth-2*border_width;
786
    canvas.height = window.innerHeight-2*border_width;
787
    canvas_pos.x = canvas.offsetLeft+border_width;
788
    canvas_pos.y = canvas.offsetTop+border_width;
789
}
790

    
791
canvas_resize = function() {
792
    canvas_set_size();
793
    putImage(last.x, last.y);
794
}
795

    
796
function paramIn(e) {
797
    e = e || window.event; 
798
    var relatedTarget = e.relatedTarget || e.fromElement; 
799
    
800
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
801
        relatedTarget = relatedTarget.parentNode;
802
    }
803
    
804
    if (relatedTarget != adding && relatedTarget != localisation) {
805
        document.removeEventListener('keydown', keys, false);
806
    }
807
}
808

    
809
function paramOut(e) {
810
         
811
    e = e || window.event; 
812
    var relatedTarget = e.relatedTarget || e.toElement; 
813
 
814
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
815
        relatedTarget = relatedTarget.parentNode;
816
    }
817
 
818
    if (relatedTarget != adding && relatedTarget != localisation) {
819
            document.addEventListener('keydown', keys, false);
820
    }
821
 
822
}
823

    
824
window.onload = function() {        
825
    pt_alt = document.getElementById('pos_alt').childNodes[0].nodeValue;
826
    pt_lat = document.getElementById('pos_lat').childNodes[0].nodeValue;
827
    pt_lon = document.getElementById('pos_lon').childNodes[0].nodeValue;
828

    
829
    localisation = document.getElementById("locadraw");
830
    adding = document.getElementById("adding");
831
    canvas = document.getElementById("mon-canvas");
832
    cntext = canvas.getContext("2d");
833
    canvas_set_size();
834
    canvas.addEventListener("click", check_links, false);
835
    //canvas.addEventListener("oncontextmenu", manage_ref_points, false);
836
    canvas.oncontextmenu = manage_ref_points;
837
    canvas.addEventListener("mouseout" , clean_canvas_events, false);
838
    show_links();
839

    
840
    var max_zoom = zooms.length - 1;
841
    zoom_control = document.getElementById("zoom_ctrl");
842
    zoom_control.onchange = change_zoom;
843
    zoom_control.max = max_zoom;
844
    if (to_zoom > max_zoom) to_zoom = Math.floor(max_zoom/2);
845
    zm = zooms[to_zoom];
846
    zoom_control.value = to_zoom;
847
    zm.refresh();
848

    
849
    zoom = zm.value;
850
    tile = zm.tile;
851
    ntiles = zm.ntiles;
852

    
853
    angle_control = document.getElementById("angle_ctrl");
854
    angle_control.value = to_cap;
855
    angle_control.onchange = change_angle;
856
    angle_control.onclick = change_angle;
857
    elvtn_control = document.getElementById("elvtn_ctrl");
858
    elvtn_control.value = to_ele;
859
    elvtn_control.onchange = change_angle;
860
    elvtn_control.onclick = change_angle;
861

    
862
    change_angle();
863
    loca_temp = document.getElementById("loca_show");
864
    if (loca_temp) {
865
        loca_temp.onclick = showLoca;
866
        loca_temp = document.getElementById("loca_hide");
867
        loca_temp.onclick = hideLoca;
868
        loca_temp = document.getElementById("loca_button");
869
        loca_temp.onclick = localate_point;
870
        loca_erase = document.getElementById("loca_erase");
871
        loca_erase.onclick = erase_point;
872
        localisation.addEventListener('mouseover',paramIn,false);
873
        localisation.addEventListener('mouseout',paramOut,false);
874
    }
875
    canvas.addEventListener('mousedown', onImageClick, false);
876
    document.addEventListener('keydown', keys, false);
877
    canvas.addEventListener('mousewheel', wheel_zoom, false);
878
    window.onresize = canvas_resize;
879
    if (adding) {
880
        document.getElementById("paramFormHide").onclick = hideForm;
881
        document.getElementById("paramFormShow").onclick = showForm;
882
        adding.addEventListener('mouseover', paramIn, false);
883
        adding.addEventListener('mouseout', paramOut, false);
884
    }
885
};