Projet

Général

Profil

Paste
Télécharger (34 ko) Statistiques
| Branche: | Révision:

root / js / pano.js @ 8697fbab

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

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

    
43

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

    
65

    
66

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

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

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

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

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

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

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

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

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

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

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

    
193
    if (twidth) {
194
        cntext.restore();
195
    }
196

    
197
}
198

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

    
205
    var alt1 = pt_alt;
206
    var lat1 = pt_lat*Math.PI/180;
207
    var lon1 = pt_lon*Math.PI/180;
208
    var alt2 = alt;
209
    var lat2 = lat*Math.PI/180;
210
    var lon2 = lon*Math.PI/180;
211

    
212
    var dLat = lat2-lat1;
213
    var dLon = lon2-lon1;
214

    
215
    var a = Math.sin(dLat/2)*Math.sin(dLat/2) + Math.sin(dLon/2)*Math.sin(dLon/2)*Math.cos(lat1)*Math.cos(lat2);  //
216
    var angle = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
217
    var d = angle*rt;                    // distance du point en Kms
218

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

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

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

    
248
function display_temp(d,cap,ele) {
249
    point_list[point_list.length] = new Array("point temporaire", d,cap,ele, "temporary");
250
    reset_zooms();
251
    putImage(last.x, last.y);
252
}
253

    
254
function arrayUnset(array, value){
255
    array.splice(array.indexOf(value), 1);
256
}
257

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

    
269
/** Returns a 3-width zero-padded version of an int
270
 * ex: 3 -> "003"
271
 */
272
function zero_pad(number) {
273
        var temp = number.toString(10);
274
        while (temp.length < 3) {
275
                temp = '0' + temp;
276
        }
277
        return temp;
278
}
279

    
280
function get_file_name(x, y, z) { // recherche du fichier correspondant au zoom et à la position
281
        return img_prefix+'/'+zero_pad(z)+'_'+zero_pad(x)+'_'+zero_pad(y)+'.jpg';
282
}
283

    
284
function get_base_name() {
285
        /** 
286
         * @returns the base name, which is the name (not path) of the folder where
287
         * the tiles are.
288
         */
289
        return img_prefix.split('/').reverse()[0];
290
}
291

    
292

    
293
function keys(key) {
294

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

    
349
function onImageClick(e) {
350
    hide_contextmenu();
351
    var index = {};
352
    if (e.touches && e.touches.length == 2) {
353
        e.preventDefault();
354
        fingr = Math.sqrt((e.touches[0].clientX - e.touches[1].clientX)^2 +
355
                          (e.touches[0].clientY - e.touches[1].clientY)^2);
356
    } else {
357
        if (e.touches) {
358
            e.preventDefault();
359
            index.x = e.changedTouches[0].clientX;
360
            index.y = e.changedTouches[0].clientY;
361
        } else {
362
            index.x = e.pageX;
363
            index.y = e.pageY;
364
        }
365

    
366
        shift.x = last.x;
367
        shift.y = last.y;
368
        speed.x = 0;
369
        speed.y = 0;
370
        mouse.x = index.x;
371
        mouse.y = index.y;
372
    }
373
    clearTimeout(tmt);  //arrêt de l'éffet eventuel d'amorti en cours.
374
    canvas.addEventListener('mousemove', stickImage, false);
375
    canvas.addEventListener('touchmove', stickImage, false);
376
    canvas.addEventListener('mouseup', launchImage, false);
377
    canvas.addEventListener('touchend', launchImage, false);
378
    //canvas.addEventListener('mouseout', launchImage, false);
379
    canvas.style.cursor='move';
380
    //document.onmousemove = stickImage;
381
    //document.onmouseup = launchImage;
382
    hide_links();
383
}
384

    
385

    
386
function stickImage(e) {
387
    var index = {};
388
    if (e.changedTouches && e.changedTouches.length == 2) {
389
        e.preventDefault();
390
        // cas du zoom à 2 doigts
391
        var nfingr = Math.sqrt((e.changedTouches[0].clientX - e.changedTouches[1].clientX)^2 +
392
                               (e.changedTouches[0].clientY - e.changedTouches[1].clientY)^2);
393
        var evt = {}
394
        evt.pageX = (e.changedTouches[0].clientX + e.changedTouches[1].clientX)/2;
395
        evt.pageY = (e.changedTouches[0].clientY + e.changedTouches[1].clientY)/2;
396
        if (fingr > nfingr*2 || fingr < nfingr/2) {
397
            evt.wheelDelta = fingr - nfingr;
398
            fingr = nfingr;
399
            return wheel_zoom(evt);
400
        } else {
401
            return;
402
        }
403
    }
404
    if (e.touches) {
405
        e.preventDefault();
406
        index.x = e.changedTouches[0].clientX;
407
        index.y = e.changedTouches[0].clientY;
408
    } else {
409
        index.x = e.pageX;
410
        index.y = e.pageY;
411
    }
412

    
413
    var xs = mouse.x - index.x + shift.x;
414
    var ys = mouse.y - index.y + shift.y;
415
    speed.x = xs - last.x;  //mémorisation des vitesses horizontales
416
    speed.y = ys - last.y;  //et verticales lors de ce déplacement
417
    putImage(xs, ys);
418
}
419

    
420
function launchImage(e) {
421
    var index = {};
422
    if (e.touches) {
423
        e.preventDefault();
424
        index.x = e.changedTouches[0].clientX;
425
        index.y = e.changedTouches[0].clientY;
426
    } else {
427
        index.x = e.pageX;
428
        index.y = e.pageY;
429
    }
430
    distort_canvas(0);
431
    canvas.removeEventListener('mousemove', stickImage, false);
432
    canvas.removeEventListener('touchmove', stickImage, false);
433
    //document.onmousemove = null;
434
    shift.x = index.x - mouse.x + shift.x;
435
    shift.y = index.y - mouse.y + shift.y;
436
    tmt = setTimeout(inertialImage, 100);
437
}
438

    
439
function putImage(x, y) { // est destiné à permettre l'effet d'amortissement par la mémorisation de la position courante.
440
    if (!zm.is_updated) return;
441
    if (x >= zm.im.width) {   // rebouclage horizontal
442
        shift.x -= zm.im.width;
443
        x -= zm.im.width;
444
    } else if (x < 0) {
445
        shift.x += zm.im.width;
446
        x += zm.im.width;
447
    }
448
    if (y >= zm.im.height) {   // pas de rebouclage vertical mais blocage
449
        //distort_canvas(1, x, y);
450
        shift.y = zm.im.height-1;
451
        y = zm.im.height-1;
452
    } else if (y < 0) {
453
        //distort_canvas(-1, x, y);
454
        shift.y = 0;
455
        y = 0;
456
    }
457

    
458
    last.x = x;
459
    last.y = y;
460
    draw_image(x, y);
461
}
462

    
463
function inertialImage() {
464
    speed.x *= 0.9;
465
    speed.y *= 0.9;
466
    if (Math.abs(speed.x) > 2 || Math.abs(speed.y) > 2) {
467
        putImage(last.x+speed.x, last.y+speed.y);
468
        tmt = setTimeout(inertialImage, 100);
469
    } else {
470
        show_links();
471
    }
472
}
473

    
474
function tri_ref_points(v1, v2) {
475
    return v1['x'] - v2['x'];
476
}
477

    
478

    
479

    
480
function tzoom(zv) {
481
    this.value = zv;
482
    this.ntiles = {x:0,y:0};
483
    this.tile = {width:0,height:0};
484
    this.last_tile = {width:0,height:0};
485
    this.max_tile = {width:0,height:0};
486
    this.im = {width:0,height:0};
487
    this.is_updated = false;
488

    
489
    this.refresh = function() {
490
            this.im.visible_width = this.tile.width*(this.ntiles.x-1)+this.last_tile.width;
491
            this.is_updated = true;
492

    
493
            this.im.width = this.im.visible_width;
494
            this.im.height = this.tile.height*(this.ntiles.y-1)+this.last_tile.height;
495
            if (this.last_tile.width > this.tile.width) {
496
                    this.max_tile.width = this.im.last_tile.width;
497
            } else {
498
                    this.max_tile.width = this.tile.width;
499
            }
500
            if (this.last_tile.height > this.tile.height) {
501
                    this.max_tile.height = this.im.last_tile.height;
502
            } else {
503
                    this.max_tile.height = this.tile.height;
504
            }
505

    
506
            var ord_pts = new Array();
507
            for(var label in ref_points) {
508
                    ord_pts.push(ref_points[label]);
509
            }
510
            ord_pts = ord_pts.sort(tri_ref_points);
511
            is_located = (ord_pts.length > 1) 
512
                          || image_loop && (ord_pts.length > 0);
513

    
514

    
515
            var alpha_domain = {start:0, end:360};
516
            this.pixel_y_ratio = this.im.width/360;
517
            if (is_located) {
518
                    this.ref_pixels = new Array;
519
                    this.ref_pixels[0] = new Array();    // Attention il faut compter un intervalle de plus !
520
                    for (var i=0; i < ord_pts.length; i++) { // premier parcours pour les paramètres cap/x
521
                            this.ref_pixels[i+1] = new Array();
522
                            this.ref_pixels[i+1].x = Math.floor(ord_pts[i].x*this.im.width);
523
                            this.ref_pixels[i+1].cap = fmodulo(ord_pts[i].cap, 360);
524
                            if (i != ord_pts.length-1) {
525
                                    this.ref_pixels[i+1].ratio_x = (ord_pts[i+1].x - ord_pts[i].x) /
526
                                            fmodulo(ord_pts[i+1].cap - ord_pts[i].cap, 360)*this.im.width;
527
                            }
528
                    }
529
                    if (image_loop == true) {
530
                            var dpix = this.im.width;
531
                            var dangle = 360;
532
                            if (ord_pts.length > 1) {
533
                                    dpix = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
534
                                    dangle = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[this.ref_pixels.length-1].cap, 360);
535
                            }
536
                            this.ref_pixels[0].ratio_x = dpix/dangle;
537
                            this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[0].ratio_x;
538
                            dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
539
                            this.ref_pixels[0].cap = fmodulo(this.ref_pixels[ord_pts.length].cap + dpix / this.ref_pixels[0].ratio_x, 360);
540
                    } else {
541
                            this.ref_pixels[0].ratio_x = this.ref_pixels[1].ratio_x;
542
                            this.ref_pixels[ord_pts.length].ratio_x = this.ref_pixels[ord_pts.length-1].ratio_x;
543
                            this.ref_pixels[0].cap = fmodulo(this.ref_pixels[1].cap - this.ref_pixels[1].x / this.ref_pixels[1].ratio_x, 360);
544
                            alpha_domain.start = this.ref_pixels[0].cap;
545
                            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);
546
                            this.pixel_y_ratio = this.im.width/fmodulo(alpha_domain.end-alpha_domain.start, 360);
547
                    }
548
                    this.ref_pixels[0].x = 0;
549

    
550
                    for (var i=0; i < ord_pts.length; i++) { // second parcours pour les paramètres elevation/y
551
                            this.ref_pixels[i+1].shift_y = Math.floor(this.pixel_y_ratio*ord_pts[i].ele - ord_pts[i].y*this.im.height);
552
                            if (i != ord_pts.length-1) {
553
                                    var next_shift = Math.floor(this.pixel_y_ratio*ord_pts[i+1].ele - ord_pts[i+1].y*this.im.height);
554
                                    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);
555
                            }
556
                    }
557

    
558
                    if (image_loop == true) {
559
                            var dpix  = this.im.width;
560
                            var delt = 0;
561
                            if (ord_pts.length > 1) {
562
                                    dpix  = this.im.width - this.ref_pixels[this.ref_pixels.length-1].x + this.ref_pixels[1].x;
563
                                    delt = this.ref_pixels[this.ref_pixels.length-1].shift_y - this.ref_pixels[1].shift_y;
564
                            }
565
                            this.ref_pixels[0].dshft_y = -delt/dpix;
566
                            this.ref_pixels[ord_pts.length].dshft_y = this.ref_pixels[0].dshft_y;
567
                            dpix = this.im.width - this.ref_pixels[ord_pts.length].x;
568
                            this.ref_pixels[0].shift_y = this.ref_pixels[ord_pts.length].shift_y + dpix*this.ref_pixels[0].dshft_y;
569
                    } else {
570
                            this.ref_pixels[0].shift_y = this.ref_pixels[1].shift_y;
571
                            this.ref_pixels[0].dshft_y = 0;
572
                            this.ref_pixels[ord_pts.length].dshft_y = 0;
573
                    }
574

    
575
                    if (debug_mode) {
576
                            var res = document.getElementById('res');
577
                            res.innerHTML = 'liste des '+this.ref_pixels.length+' valeurs de correction (image = '+this.im.width+'x'+this.im.height+') zoom = '+this.value+':<br/>';
578
                            for (var i=0; i < this.ref_pixels.length; i++) { // pour le debug
579
                                    res.innerHTML += '<p>point '+i+' :</p><ul>';
580
                                    for (var key in this.ref_pixels[i]) { // pour le debug
581
                                            res.innerHTML += '<li>'+key + '['+i+'] = '+this.ref_pixels[i][key]+'</li>';
582
                                    }
583
                                    if (i != this.ref_pixels.length-1) {
584
                                            var tx0 = this.ref_pixels[i+1].x-1;
585
                                            //var ty0 = this.ref_pixels[i+1].shift_y;
586
                                            var ty0 = 0;
587
                                    } else {
588
                                            var tx0 = this.im.width-1;
589
                                            var ty0 = 0;
590
                                    }
591
                                    res.innerHTML += '</ul><p>test sur : '+tx0+','+ty0+'</p>';
592
                                    var tst = this.get_cap_ele(tx0, ty0);
593
                                    res.innerHTML += '<p>cap:'+tst.cap+', ele:'+tst.ele+'</p>';
594
                                    var tst2 = this.get_pos_xy(tst.cap, tst.ele);
595
                                    res.innerHTML += '</ul><p>x:'+tst2.x+', y:'+tst2.y+'</p>';
596
                            }
597
                    }
598
            }
599

    
600
            this.pt_list = new Array();
601
            for (var i=0; i<point_list.length; i++) {
602
                    var lbl = point_list[i][0];
603
                    var dst = point_list[i][1];
604
                    var cap = point_list[i][2];
605
                    var ele = point_list[i][3];
606
                    var lnk = point_list[i][4];
607
                    var typ = 'unlocated';
608
                    var rxy = this.get_pos_xy(cap, ele);
609
                    var is_visible = (
610
                            fmodulo(cap - alpha_domain.start, 360) 
611
                                    <= 
612
                                    fmodulo(alpha_domain.end - 
613
                                            alpha_domain.start -0.0001, 360)+0.0001 
614
                                    && is_located);
615

    
616
                    this.pt_list[i] = new Array();
617
                    if (ref_points[lbl] != undefined) {
618
                            typ = 'ref_point';
619
                            if (!is_located) { 
620
                                    rxy = {
621
                                            x:ref_points[lbl].x*this.im.width, 
622
                                            y:ref_points[lbl].y*this.im.height
623
                                    };
624
                            }
625
                    } else if(lnk == '' && is_visible && lbl != 'point temporaire') {
626
                            typ = 'loc_point';
627
                    }else if(is_visible && lbl =='point temporaire') {
628
                            typ = 'temporary';
629

    
630
                    } else if(is_visible) {
631
                            typ = 'pano_point';
632
                            lnk += '&to_zoom='+this.value;
633
                    }
634
                    this.pt_list[i]['type'] = typ;
635
                    this.pt_list[i]['cap'] = cap;
636
                    this.pt_list[i]['ele'] = ele;
637
                    this.pt_list[i]['dist'] = dst;
638
                    this.pt_list[i]['label'] = lbl;
639
                    this.pt_list[i]['lnk'] = lnk;
640
                    this.pt_list[i]['xc'] = rxy.x;
641
                    this.pt_list[i]['yc'] = Math.floor(this.im.height/2 - rxy.y);
642
            }
643
    },
644

    
645
    this.get_tile_size = function(nx, ny) {
646
        var res = {width:0, height:0};
647
        if (nx == this.ntiles.x-1) res.width = this.last_tile.width;
648
        else res.width = this.tile.width;
649
        if (ny == this.ntiles.y-1) res.height = this.last_tile.height;
650
        else res.height = this.tile.height;
651
        return res;
652
    }
653

    
654
    this.get_cap_ele = function(px, py) {               // recherche d'un cap et d'une élévation à partir d'un pixel X,Y.
655
        if (is_located) {
656
            for (var i=0; i < this.ref_pixels.length; i++) {
657
                if (i == this.ref_pixels.length - 1 || px < this.ref_pixels[i+1].x) {
658
                    var dpix = px-this.ref_pixels[i].x;
659
                    var cp = fmodulo(this.ref_pixels[i].cap + dpix/this.ref_pixels[i].ratio_x, 360);
660
                    var el = (py+this.ref_pixels[i].shift_y+this.ref_pixels[i].dshft_y*dpix)/this.pixel_y_ratio;
661
                    return {cap:cp, ele:el};
662
                }
663
            }
664
        } else {
665
            var cp = 360*px/this.im.width;
666
            var el = 360*py/this.im.height;
667
            return {cap:cp, ele:el};
668
        }
669
    }
670

    
671
    this.get_pos_xy = function(cap, ele) {                  // recherche des coordonnées pixel à partir d'un cap et d'une élévation.
672
        if (is_located) {
673
            var dcap = fmodulo(cap-this.ref_pixels[0].cap, 360);
674
            for (var i=0; i < this.ref_pixels.length; i++) {
675
                if (i == this.ref_pixels.length - 1 || dcap < fmodulo(this.ref_pixels[i+1].cap-this.ref_pixels[0].cap, 360)) {
676
                    var px = this.ref_pixels[i].x + this.ref_pixels[i].ratio_x*fmodulo(cap - this.ref_pixels[i].cap, 360);
677
                    var dpix = px-this.ref_pixels[i].x;
678
                    var py = this.pixel_y_ratio*ele - this.ref_pixels[i].shift_y - this.ref_pixels[i].dshft_y*dpix;
679
                    return {x:px, y:py};
680
                }
681
            }
682
        } else {
683
            var px = fmodulo(cap, 360)/360*this.im.width;
684
            var py = ele/360*this.im.height;
685
            return {x:px, y:py};
686
        }
687
    }
688
}
689

    
690
function reset_zooms () {
691
    for(i=0; i<zooms.length; i++) zooms[i].is_updated = false;
692
    zm.refresh();
693
}
694

    
695
function wheel_zoom (event) {
696
    var zshift = {x:0, y:0};
697
    if (event.pageX != undefined && event.pageX != undefined) {
698
        zshift.x = event.pageX-canvas.width/2-canvas_pos.x;
699
        zshift.y = event.pageY-canvas.height/2-canvas_pos.y;
700
    }
701
    //event.preventDefault();
702
    if (event.wheelDelta < 0 && zoom_control.value < zoom_control.max) {
703
        zoom_control.value++;
704
        change_zoom(zshift.x, zshift.y);
705
    } else if (event.wheelDelta > 0 && zoom_control.value > zoom_control.min) {
706
        zoom_control.value--;
707
        change_zoom(zshift.x, zshift.y);
708
    }
709
}
710

    
711
function change_zoom(shx, shy) {
712
    var zoom_control = document.getElementById("zoom_ctrl");
713
    var v = zoom_control.value;
714

    
715
    prev_zm = zm;
716

    
717
    if (zooms[v]) {
718
        if (!zooms[v].is_updated) zooms[v].refresh();
719
    } else {
720
        zooms[v] = new tzoom(v);
721
    }
722

    
723
    if (zooms[v].is_updated) {
724
        if (shx == undefined || shy == undefined) {
725
            shx=0;
726
            shy=0;
727
        }
728
        zm = zooms[v];
729
        var px = (last.x+shx)*zm.im.width/prev_zm.im.width - shx;
730
        var py = (last.y+shy)*zm.im.height/prev_zm.im.height - shy;
731
        if (py < zm.im.height && py >= 0) {
732
            zoom = zm.value;
733
            tile = zm.tile;
734
            ntiles = zm.ntiles;
735
            putImage(px, py);
736
        } else {
737
            zm = prev_zm;
738
            zoom_control.value = zm.value;
739
        }
740
    }
741
}
742

    
743
function change_angle() {
744
    var elvtn_control = document.getElementById('elvtn_ctrl');
745
    var angle_control = document.getElementById('angle_ctrl');
746
    var resxy = zm.get_pos_xy(angle_control.value, elvtn_control.value);
747
    var pos_x = resxy.x;
748
    var pos_y = Math.floor(zm.im.height/2 - resxy.y);
749
    putImage(pos_x, pos_y);
750
}
751

    
752
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.
753
    return Math.sqrt(x*x + y*y) < r;
754
}
755

    
756
function check_links(e) {
757
    var mouse_x = e.pageX-canvas_pos.x;
758
    var mouse_y = e.pageY-canvas_pos.y;
759
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
760
    var pos_y = last.y + mouse_y - canvas.height/2;
761
    for(var i = 0; i < zm.pt_list.length; i++) {
762
        if (is_located && zm.pt_list[i]['type'] == 'pano_point') {
763
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
764
                if (zm.pt_list[i]['lnk'] != '') window.location = zm.pt_list[i]['lnk'];
765
                break;
766
            }
767
        }
768
    }
769
}
770

    
771
function display_links(e) {
772
    var index = {};
773
    if (e.touches) {
774
        e.preventDefault();
775
        index.x = e.changedTouches[0].clientX;
776
        index.y = e.changedTouches[0].clientY;
777
    } else {
778
        index.x = e.pageX;
779
        index.y = e.pageY;
780
    }
781
    var info = document.getElementById('info');
782
    var mouse_x = index.x-canvas_pos.x;
783
    var mouse_y = index.y-canvas_pos.y;
784
    var pos_x = nmodulo(last.x + mouse_x - canvas.width/2, zm.im.width);
785
    var pos_y = last.y + mouse_y - canvas.height/2;
786
    //var cap = ((pos_x/zm.im.width)*360).toFixed(2);
787
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
788
    //var ele = ((zm.im.height/2 - pos_y)/zm.im.width)*360;
789
    info.innerHTML = 'élévation : '+res.ele.toFixed(2)+'<br/>cap : '+res.cap.toFixed(2);
790
    info.style.top = index.y+'px';
791
    info.style.left = index.x+'px';
792
    info.style.backgroundColor = '#FFC';
793
    info.style.display = 'block';
794
    canvas.style.cursor='crosshair';
795
    for(var i = 0; i < zm.pt_list.length; i++) {
796
        if (is_located || zm.pt_list[i]['type'] == 'ref_point') {
797
            if (check_prox(zm.pt_list[i]['xc']-pos_x, zm.pt_list[i]['yc']-pos_y, 20)) {
798
                info.innerHTML = zm.pt_list[i]['label'];
799
                if (zm.pt_list[i]['dist'] < 10) var dst = Math.round(zm.pt_list[i]['dist']*1000)+' m';
800
                else var dst = zm.pt_list[i]['dist'].toFixed(1)+' kms';
801
                info.innerHTML += '<br/> à ' + dst;
802
                info.style.backgroundColor = 'rgb('+point_colors[zm.pt_list[i]['type']]+')';
803
                canvas.style.cursor='auto';
804
                break;
805
            }
806
        }
807
    }
808
}
809

    
810
function hide_links() {
811
    canvas.removeEventListener( "mousemove", display_links, false);
812
    canvas.removeEventListener( "touchmove", display_links, false);
813
    var info = document.getElementById('info');
814
    info.style.display = 'none';
815
}
816

    
817
function show_links() {
818
    canvas.addEventListener( "mousemove", display_links, false);
819
    canvas.addEventListener( "touchmove", display_links, false);
820
//    var info = document.getElementById('info');
821
//    info.style.display = 'block';
822
}
823

    
824
function hide_contextmenu() {
825
    document.getElementById('insert').style.display = 'none';
826
}
827

    
828
function manage_ref_points(e) {
829
    //event.preventDefault();
830
    //event.stopPropagation();
831
        var sel_pt = document.getElementById('sel_point');
832
    var do_insert = document.getElementById('do-insert');
833
        var do_delete = document.getElementById('do-delete');
834
        var do_cancel = document.getElementById('do-cancel');
835
        var show_cap = document.getElementById('show-cap');
836
        var insrt = document.getElementById('insert');
837

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

    
841
        insrt.style.left = e.pageX+'px';
842
        insrt.style.top = e.pageY+'px';
843
        insrt.style.display = 'block';
844

    
845
        if (do_insert) {// true if there are ref points
846
                    for(var i = 0; i < zm.pt_list.length; i++) {
847
                            if (zm.pt_list[i]['type'] == 'ref_point') {
848
                                    if (check_prox(zm.pt_list[i]['xc']-pos_x,
849
                                                   zm.pt_list[i]['yc']-pos_y, 20)) {
850
                                            sel_pt.value = zm.pt_list[i]['label'];
851
                                    }
852
                            }
853
                    }
854
                do_delete.onclick = function() {delete_ref_point(insrt)};
855
                do_insert.onclick = function() {insert_ref_point(insrt, e.pageX-canvas_pos.x, e.pageY-canvas_pos.y)};
856
                show_cap.onclick = function() {
857
                        window.open('show_capline.php?title='+encodeURIComponent(btoa(title))+'&cap='+res.cap+'&org_lat='+pt_lat+'&org_lon='+pt_lon+'&dist=120000');
858
                };
859
        }
860

    
861
        do_cancel.onclick = hide_contextmenu;
862
    var res = zm.get_cap_ele(pos_x, zm.im.height/2 - pos_y);
863
    var pt_lat = document.getElementById('pos_lat').childNodes[0].nodeValue;
864
    var pt_lon = document.getElementById('pos_lon').childNodes[0].nodeValue;
865
    return false;
866
}
867

    
868
function insert_ref_point(el, x, y) {
869
        var label, posx, posy;
870
        el.style.display = 'none';
871
        var selected_label = document.getElementById('sel_point').value;
872
        var found = false;
873
    for(var i = 0; i < zm.pt_list.length; i++) {
874
        label = zm.pt_list[i]['label'];
875
        if(label == selected_label) {
876
            posx = nmodulo(last.x + x - canvas.width/2, zm.im.width)/zm.im.width;
877
            posy = 0.5 - (last.y + y - canvas.height/2)/zm.im.height;
878
            var pval = {x:posx, y:posy, cap:zm.pt_list[i]['cap'], ele:zm.pt_list[i]['ele'], label:label};
879
            ref_points[label] = pval;
880
            document.getElementById('res').innerHTML = '<h4>Dernier point entré</h4>';
881
            document.getElementById('res').innerHTML += '<p>reference["'+label+'"] = '+posx.toFixed(5)+','+posy.toFixed(5)+'</p>';
882
            reset_zooms();
883
            putImage(last.x, last.y);
884
            found = true;
885
            break;
886
        }
887
    }
888
        if (!found) {
889
                alert('unknown ref_point: '+label);
890
        }
891
        show_result();
892
        
893
        // Then push the modif
894
        var xhr = getXMLHttpRequest();
895
        xhr.open("POST", "ajax/add_reference.php", true);
896
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
897
        xhr.send("ref_point="+encodeURIComponent(label)
898
                 +"&panorama="+encodeURIComponent(get_base_name())
899
                 +"&x="+posx+"&y="+posy);
900
}
901

    
902
function show_result(clear_before) {
903
    var res = document.getElementById('res');
904
    var strg = '';
905
    for (var lbl in ref_points) {
906
        strg += '<li>reference["'+lbl+'"] = '+ref_points[lbl].x.toFixed(5)+','+ref_points[lbl].y.toFixed(5)+'</li>';
907
    }
908
    if (strg) strg = '<h3>Liste de tous les points de référence</h3>\n<ul>' + strg + '</ul>';
909
    if (clear_before) res.innerHTML = strg;
910
    else res.innerHTML += strg;
911
}
912

    
913
function delete_ref_point(el) {
914
        var ref_name = document.getElementById('sel_point').value;
915
    el.style.display = 'none';
916
    delete ref_points[ref_name];
917
    reset_zooms();
918
    putImage(last.x, last.y);
919
        show_result(true);
920
        
921
        // Then push the modif
922
        var xhr = getXMLHttpRequest();
923
        xhr.open("POST", "ajax/rm_reference.php", true);
924
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
925
        xhr.send("ref_point="+encodeURIComponent(ref_name)
926
                 +"&panorama="+encodeURIComponent(get_base_name()));
927
}
928

    
929
function clean_canvas_events(e) {
930
    canvas.removeEventListener('mousemove', stickImage, false);
931
    canvas.removeEventListener('touchmove', stickImage, false);
932
    document.getElementById('info').style.display = 'none';
933
    speed.x = 0;
934
    speed.y = 0;
935
}
936

    
937
canvas_set_size = function() {
938
    canvas.style.border = border_width+"px solid red";
939
    canvas.width = window.innerWidth-2*border_width;
940
    canvas.height = window.innerHeight-2*border_width;
941
    canvas_pos.x = canvas.offsetLeft+border_width;
942
    canvas_pos.y = canvas.offsetTop+border_width;
943
}
944

    
945
canvas_resize = function() {
946
    canvas_set_size();
947
    putImage(last.x, last.y);
948
}
949

    
950
function paramIn(e) {
951
    e = e || window.event;
952
    var relatedTarget = e.relatedTarget || e.fromElement;
953

    
954
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
955
        relatedTarget = relatedTarget.parentNode;
956
    }
957

    
958
    if (relatedTarget != adding && relatedTarget != localisation) {
959
        document.removeEventListener('keydown', keys, false);
960
    }
961
}
962

    
963
function paramOut(e) {
964

    
965
    e = e || window.event;
966
    var relatedTarget = e.relatedTarget || e.toElement;
967

    
968
    while (relatedTarget != adding && relatedTarget.nodeName != 'BODY' && relatedTarget != document && relatedTarget != localisation) {
969
        relatedTarget = relatedTarget.parentNode;
970
    }
971

    
972
    if (relatedTarget != adding && relatedTarget != localisation) {
973
            document.addEventListener('keydown', keys, false);
974
    }
975

    
976
}
977

    
978

    
979
function load_pano() {
980
        localisation = document.getElementById("locadraw");
981
    adding = document.getElementById("adding");
982
    canvas = document.getElementById("mon-canvas");
983
    cntext = canvas.getContext("2d");
984
    canvas_set_size();
985
    canvas.addEventListener("click", check_links, false);
986
    //canvas.addEventListener("oncontextmenu", manage_ref_points, false);
987
    canvas.oncontextmenu = manage_ref_points;
988
    canvas.addEventListener("mouseout" , clean_canvas_events, false);
989
    show_links();
990

    
991
    var max_zoom = zooms.length - 1;
992
    zoom_control = document.getElementById("zoom_ctrl");
993
    zoom_control.onchange = change_zoom;
994
    zoom_control.max = max_zoom;
995
    if (to_zoom > max_zoom) to_zoom = Math.floor(max_zoom/2);
996
    zm = zooms[to_zoom];
997
    zoom_control.value = to_zoom;
998
    zm.refresh();
999

    
1000
    zoom = zm.value;
1001
    tile = zm.tile;
1002
    ntiles = zm.ntiles;
1003

    
1004
    angle_control = document.getElementById("angle_ctrl");
1005
    angle_control.value = to_cap;
1006
    angle_control.onchange = change_angle;
1007
    angle_control.onclick = change_angle;
1008
    elvtn_control = document.getElementById("elvtn_ctrl");
1009
    elvtn_control.value = to_ele;
1010
    elvtn_control.onchange = change_angle;
1011
    elvtn_control.onclick = change_angle;
1012

    
1013
    change_angle();
1014
    loca_temp = document.getElementById("loca_show");
1015
    if (loca_temp) {
1016
        loca_temp.onclick = showLoca;
1017
        loca_temp = document.getElementById("loca_hide");
1018
        loca_temp.onclick = hideLoca;
1019
        loca_temp = document.getElementById("loca_button");
1020
        loca_temp.onclick = localate_point;
1021
        loca_erase = document.getElementById("loca_erase");
1022
        loca_erase.onclick = erase_point;
1023
        localisation.addEventListener('mouseover',paramIn,false);
1024
        localisation.addEventListener('mouseout',paramOut,false);
1025
    }
1026
    canvas.addEventListener('mousedown', onImageClick, false);
1027
    canvas.addEventListener('touchstart', onImageClick, false);
1028
    document.addEventListener('keydown', keys, false);
1029
    canvas.addEventListener('mousewheel', wheel_zoom, false);
1030
    window.onresize = canvas_resize;
1031
    if (adding) {
1032
        document.getElementById("paramFormHide").onclick = hideForm;
1033
        document.getElementById("paramFormShow").onclick = showForm;
1034
        adding.addEventListener('mouseover', paramIn, false);
1035
        adding.addEventListener('mouseout', paramOut, false);
1036
    }
1037
};