logo CNRS

ForeFire

logo UNIV
  1 var phpDir = "http://forefire.univ-corse.fr/api/v1/php/";
  2 var requestType = "POST";
  3 
  4 var scripts = document.getElementsByTagName('script');
  5 var srcval = scripts[scripts.length - 1].src;
  6 if (srcval.search("\\?") != -1)
  7 {
  8     var vars = srcval.split("?")[1];
  9     var elements = vars.split("&");
 10 
 11     for (var exp in elements)
 12     {
 13         var element = elements[exp].split("=");
 14 
 15         if (element[0] == "requestType" && (element[1].toUpperCase() == "POST" || element[1].toUpperCase() == "GET"))
 16         {
 17             requestType = element[1];
 18         }
 19         else if (element[0] == "phpDir")
 20         {
 21             phpDir = element[1];
 22             if (phpDir.charAt(phpDir.length - 1) != "/")
 23                 phpDir += "/";
 24         }
 25     }
 26 }
 27 
 28 /**
 29  * Class handling a simulation
 30  * @class
 31  * @param {String} [ref] Reference to a working directory to reload a simulation
 32  */
 33 function Firesim(ref)
 34 {
 35     //**********************************************************
 36     // Attributes
 37     //**********************************************************
 38 
 39     var reference = (ref) ? ref : Firesim.dateFormat(new Date(), "-", "_", "-", "");
 40     var outputInterval = 1000;
 41     var numberOfSteps = 10;
 42 
 43     //**********************************************************
 44     // Getters
 45     //**********************************************************
 46 
 47     /**
 48      * Returns the working directory
 49      * @returns {String} Working Directory
 50      */
 51     Firesim.prototype.getReference = function() {
 52         return reference;
 53     };
 54 
 55     /**
 56      * Returns the output interval in ms
 57      * @returns {Number}
 58      */
 59     Firesim.prototype.getOutputInterval = function() {
 60         return outputInterval;
 61     };
 62 
 63     /**
 64      * Returns the number of steps
 65      * @returns {Number}
 66      */
 67     Firesim.prototype.getNumberOfSteps = function() {
 68         return numberOfSteps;
 69     };
 70 
 71     //**********************************************************
 72     // Setters
 73     //**********************************************************
 74 
 75     /**
 76      * Defines the output interval for {@link Firesim#engage} or {@link Firesim#engageInTimemap}
 77      * @param {Number} millis Time in ms
 78      */
 79     Firesim.prototype.setOutputInterval = function(millis) {
 80         outputInterval = millis;
 81     };
 82 
 83     /**
 84      * Defines the number of steps for {@link Firesim#engage} or {@link Firesim#engageInTimemap}
 85      * @param {Number} number 
 86      */
 87     Firesim.prototype.setNumberOfSteps = function(number) {
 88         numberOfSteps = number;
 89     };
 90 }
 91 
 92 //**********************************************************
 93 // Methods
 94 //**********************************************************
 95 
 96 /**
 97  * Initialize a simulation
 98  * @param {Number} lat Latitude
 99  * @param {Number} lng Longitude
100  * @param {Date} date Date
101  * @param {Number} windX Wind on X axis
102  * @param {Number} windY Wind on Y axis
103  * @param {String} [fuelModel] Algorithm and Threat (default: B1R4)
104  */
105 Firesim.prototype.init = function(lat, lng, date, windX, windY, fuelModel) {
106     fuelModel = (fuelModel) ? fuelModel : "B1R4";
107     var encodedCoords = Firesim.encodePoly([[lat, lng]]);
108 
109     $.ajax({
110         url: phpDir + "forefireAPI.php",
111         type: requestType,
112         data: {
113             command: "init",
114             path: this.getReference(),
115             message: "CEMER",
116             coords: encodedCoords,
117             ventX: windX,
118             ventY: windY,
119             date: Firesim.dateFormat(date, "-", "_", ":", ""),
120             fuelModel: fuelModel + ".xml"
121         }
122     });
123 };
124 
125 /**
126  * Initialize a simulation from a Polyline
127  * @param {Array|String} polyline Array of coordinates ex: [[42, 9], [42.1, 8.9]]
128  * @param {Date} date Date
129  * @param {Number} windX Wind on X axis
130  * @param {Number} windY Wind on Y axis
131  * @param {Boolean} [alreadyEncoded] If true, the polyline is already encoded (default: false)
132  * @param {String} [fuelModel] Algorithm and Threat (default: B1R4)
133  */
134 Firesim.prototype.initFromPolyline = function(polyline, date, windX, windY, alreadyEncoded, fuelModel) {
135     fuelModel = (fuelModel) ? fuelModel : "B1R4";
136     alreadyEncoded = (alreadyEncoded) ? alreadyEncoded : false;
137     var encodedCoords = (alreadyEncoded == true) ? polyline : Firesim.encodePoly(polyline);
138 
139     $.ajax({
140         url: phpDir + "forefireAPI.php",
141         type: requestType,
142         data: {
143             command: "init",
144             path: this.getReference(),
145             message: "CEMER",
146             coords: encodedCoords,
147             ventX: windX,
148             ventY: windY,
149             date: Firesim.dateFormat(date, "-", "_", ":", ""),
150             fuelModel: fuelModel + ".xml"
151         }
152     });
153 };
154 
155 /**
156  * Action to realize
157  * @param {Date} date Date of the action
158  * @param {String} domain Domain of the action
159  * @param {String} action Fonction of the action
160  * @param {Array} params Array of parameters
161  * @example 
162  * var fs = new Firesim();<br>
163  * var params = [9.2, 42.3];<br>
164  * fs.addAction('2012-03-22T12:14:23Z', 'WORLD', 'addIgnition', params);<br>
165  * // Execute : 2012-03-22T12:14:23Z;WORLD;addIgnition (9.2,42.3)
166  */
167 Firesim.prototype.action = function(date, domain, action, params) {
168     var datexml = Firesim.dateFormat(date, "-", "T", ":", "Z");
169 
170     $.ajax({
171         url: phpDir + "forefireAPI.php",
172         type: requestType,
173         data: {
174             command: "action",
175             path: this.getReference(),
176             date: datexml,
177             domain: domain,
178             action: action,
179             params: params
180         }
181     });
182 };
183 
184 /**
185  * Changes the wind speed
186  * @param {Date} date Date
187  * @param {Number} windX wind on x axis 
188  * @param {Number} windY wind on y axis
189  * @see Firesim#action
190  */
191 Firesim.prototype.windSpeed = function(date, windX, windY)
192 {
193     this.action(date, 'GloablWind', 'windSpeed', [windX, windY]);
194 };
195 
196 /**
197  * Adds an ignition
198  * @param {Date} date Date
199  * @param {Number} lat Latitude of the ignition
200  * @param {Number} lng Longitude of the ignition
201  * @see Firesim#action
202  */
203 Firesim.prototype.addIgnition = function(date, lat, lng)
204 {
205     this.action(date, 'WORLD', 'addIgnition', [lng, lat]);
206 };
207 
208 /**
209  * Adds a break where fire can't burn
210  * @param {Date} date Date
211  * @param {Number} latP1 Latitude of the first point
212  * @param {Number} lngP1 Longitude of the first point
213  * @param {Number} latP2 Latitude of the second point
214  * @param {Number} lngP2 Longitude of the second point
215  * @see Firesim#action
216  */
217 Firesim.prototype.addBreak = function(date, latP1, lngP1, latP2, lngP2)
218 {
219     this.action(date, 'WORLD', 'addBreak', [lngP1, latP1, lngP2, latP2, 0, 100]);
220 };
221 
222 /**
223  * Processes the next simulation step
224  */
225 Firesim.prototype.step = function() {
226     $.ajax({
227         url: phpDir + "forefireAPI.php",
228         type: requestType,
229         data: {
230             command: "step",
231             path: this.getReference()
232         }
233     });
234 };
235 
236 /**
237  * Gets the list of state files on the server for this simulation, separated by a newline
238  * @returns {String} 
239  */
240 Firesim.prototype.getListOfStates = function() {
241     return $.ajax({
242         url: phpDir + "forefireAPI.php",
243         type: requestType,
244         async: false,
245         data: {
246             command: "getListOfStates",
247             path: this.getReference()
248         }
249     }).responseText;
250 };
251 
252 /**
253  * Get the last index of available state
254  * @returns {Number} 
255  */
256 Firesim.prototype.getLastAvailable = function() {
257     return this.getListOfStates().split("\n").length;
258 };
259 
260 /**
261  * Processes the results of a specific fire front state, uses {@link Firesim#getData}
262  * @param {String} type Returned data type ("JSON" or "KML")
263  * @param {Number} indice Index of the specific state
264  * @param {Function} fct Function processing the results with the data as parameter 
265  * @see Firesim#getLastState
266  * @see Firesim#getAllStates
267  * @example 
268  * inst.getState("JSON", 2, alert);
269  * // This will show an alert reading data of the second state as a JSON string :
270  * // {
271  * //  "fronts": [
272  * //      {
273  * //          "area":"0ha",
274  * //          "date":"2011-08-05T12:10:04Z",
275  * //          "projection":"LAMBERT2E",
276  * //          "coordinates":"8.99,41.99,0 8.9996,41.9994,0 8.99,41.99,0"
277  * //      }
278  * //  ]
279  * // }
280  */
281 Firesim.prototype.getState = function(type, indice, fct) {
282     if (type == "KML")
283         this.getData("fronts", indice, function(data){ fct(Firesim.jsonFrontsToKML(data)); });
284     else
285         this.getData("fronts", indice, fct);
286 };
287 
288 /**
289  * Processes the JSON results of a specific state of a specific element
290  * @param {String} element Data element ("fronts")
291  * @param {Number} indice Index of the specific state
292  * @param {Function} fct Function processing the results with the data as parameter 
293  * @see Firesim#getState
294  */
295 Firesim.prototype.getData = function(element, indice, fct) {
296     $.ajax({
297         url: phpDir + "forefireAPI.php",
298         type: requestType,
299         dataType: "text",
300         data: {
301             command: "getState",
302             path: this.getReference(),
303             element: element,
304             indice: indice
305         },
306         success: function(data) {
307             if (fct)
308                 fct(data);
309         }
310     });
311 };
312 
313 /**
314  * Processes the results of the last state
315  * @param {String} type Returned data type ("JSON" or "KML")
316  * @param {Function} fct Function processing the results with the data as parameter
317  * @see Firesim#getState
318  * @returns {Number} Index of the last processed state 
319  */
320 Firesim.prototype.getLastState = function(type, fct) {
321     var lastAvailable = this.getLastAvailable();
322     this.getState(type, lastAvailable, fct);
323     return lastAvailable;
324 };
325 
326 /**
327  * Processes the results of all states
328  * @param {String} type Returned data type ("JSON" or "KML")
329  * @param {Function} fct Function processing the results with the data as parameter
330  * @see Firesim#getState
331  */
332 Firesim.prototype.getAllStates = function(type, fct) {
333     this.getState(type, "all", fct);
334 };
335 
336 /**
337  * Starts a simulation and executes 'fct' for each data result
338  * @see Firesim#setNumberOfSteps
339  * @see Firesim#setOutputInterval
340  * @see Firesim#getState
341  * @param {String} type Returned data type ("JSON" or "KML")
342  * @param {Function} fct Function processing the results with the data as parameter
343  */
344 Firesim.prototype.engage = function(type, fct) {
345     var obj = this;
346     var step = 0;
347     var index = 0;
348 
349     setTimeout(function() {
350         var stepCallInterval = setInterval(function() {
351             if (index != obj.getLastAvailable())
352             {
353                 index = obj.getLastState(type, fct);
354                 obj.step();
355                 step++;
356             }
357 
358             if (step >= obj.getNumberOfSteps())
359                 clearInterval(stepCallInterval);
360         }, obj.getOutputInterval());
361     }, 2000);
362 };
363 
364 //**********************************************************
365 // Static Methods 
366 //**********************************************************
367 
368 /**
369  * Encode a polyline
370  * @static
371  * @param {Array} points Array of coordinates
372  * @returns {String} encoded polyline
373  */
374 Firesim.encodePoly = function(points) {
375     var result = "";
376     var lastPoint = [0, 0];
377     var val1, val2;
378 
379     for (var i = 0; i < points.length; i++)
380     {
381         val1 = points[i][0] - lastPoint[0];
382         val2 = points[i][1] - lastPoint[1];
383         lastPoint = points[i];
384         result += Firesim.encodeNumber(val1) + Firesim.encodeNumber(val2);
385     }
386     return result;
387 };
388 
389 /**
390  * Encode a single Number
391  * @static
392  * @param {Number} number number to encode
393  * @returns {String} encoded number
394  */
395 Firesim.encodeNumber = function(number) {
396     var result = "";
397     number = Math.round(number * 100000);
398     var decal = number << 1;
399 
400     if (decal < 0)
401         decal = ~decal;
402 
403     while (decal >= 0x20)
404     {
405         result += String.fromCharCode(((0x20 | (decal & 0x1F)) + 63));
406         decal = decal >> 5;
407     }
408 
409     result += String.fromCharCode(decal + 63);
410     return result;
411 };
412 
413 /**
414  * Decode a Polyline
415  * @static
416  * @param {String} encoded encoded polyline
417  * @returns {Array} decoded array of coordinates
418  */
419 Firesim.decodePoly = function(encoded) {
420     var index = 0;
421     var array = [];
422     var lat = 0;
423     var lng = 0;
424 
425     while (index < encoded.length)
426     {
427         var codeChar;
428         var decalage = 0;
429         var result = 0;
430         var decal = 0;
431 
432         do
433         {
434             codeChar = encoded.charCodeAt(index) - 63;
435             index++;
436             decal = (codeChar & 0x1F) << decalage;
437             result = result | decal;
438             decalage += 5;
439 
440         } while (codeChar >= 0x20);
441 
442         var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
443         lat += dlat;
444 
445         decalage = 0;
446         result = 0;
447         decal = 0;
448 
449         do
450         {
451             codeChar = encoded.charCodeAt(index) - 63;
452             index++;
453             decal = (codeChar & 0x1F) << decalage;
454             result = result | decal;
455             decalage += 5;
456 
457         } while (codeChar >= 0x20);
458 
459         var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
460         lng += dlng;
461         array.push([lat * 1e-5, lng * 1e-5]);
462     }
463 
464     return array;
465 };
466 
467 /**
468  * Formalize a date in UTC
469  * @static
470  * @example 
471  * Firesim.dateFormat(date, "_", "T", ":", "Z")
472  * returns date as : y_m_dTh:m:sZ
473  * @param {Date} date
474  * @param {String} ds
475  * @param {String} dts
476  * @param {String} ts
477  * @param {String} ec
478  * @returns {String} Formated date
479  */
480 Firesim.dateFormat = function(date, ds, dts, ts, ec) {
481     var y = date.getUTCFullYear();
482     var m = date.getUTCMonth() + 1;
483     var d = date.getUTCDate();
484     var h = date.getUTCHours();
485     var min = date.getUTCMinutes();
486     var s = date.getUTCSeconds();
487 
488     var datestr = y + ds + m + ds + d + dts + h + ts + min + ts + s + ec;
489     return datestr;
490 };
491 
492 /**
493  * Format a String to an Array of coordinates in JSON format
494  * @static
495  * @param {String} strCoords
496  * @returns {Array}
497  * @example 
498  * // Exemple of input : "42,9,0 41,8.7,0"
499  * // Exemple of output :
500  * // [{
501  * //     lat: 42,
502  * //     lon: 9,
503  * //  },
504  * //     lat: 41,
505  * //     lon: 8.7
506  * // }]
507  */
508 Firesim.coordsFormat = function(strCoords) {
509     var out = [];
510     var points = strCoords.split(' ');
511 
512     for (var i = 0; i < points.length; i++)
513     {
514         var splitedPoints = points[i].split(',');
515         out.push({
516             lat: splitedPoints[1],
517             lon: splitedPoints[0]
518         });
519     }
520 
521     return out;
522 };
523 
524 /**
525  * Format a JSON output (for exemple from {@link Firesim#getState}) to a KML string
526  * @static
527  * @param {String} jsonStr JSON string
528  * @returns {String} KML string
529  */
530 Firesim.jsonFrontsToKML = function(jsonStr) {
531     var json = JSON.parse(jsonStr);
532     var fronts = json["fronts"];
533     
534     var str = "<Document>";
535         str += "<Folder>";
536             for (var i = 0; i < fronts.length; i++)
537             {
538                 str += "<Placemark>";
539                     str += "<TimeStamp>";
540                         str += "<when>"+fronts[i]["date"]+"</when>";
541                     str += "</TimeStamp>";
542                     str += "<name>"+fronts[i]["area"]+"</name>";
543                     str += "<LineString>";
544                         str += "<extrude>1</extrude>";
545                         str += "<tessellate>1</tessellate>";
546                         str += "<altitudeMode>relativeToGround</altitudeMode>";
547                         str += "<coordinates>"+fronts[i]["coordinates"]+"</coordinates>";
548                     str += "</LineString>";
549                 str += "</Placemark>";
550             }
551         str += "</Folder>";
552     str += "</Document>";
553     
554     return str;
555 };
556 
557 /**
558  * Get ASD for a given Array of coordinates
559  * @static
560  * @param {Array} points Coordinates
561  * @param {Function} fct Function processing the results with the data as parameter
562  * @param {String} [fuelModel] Algorithm and Threat (default: B1R4)
563  * @param {Number} index Index in the fuelModel file
564  * @ignore
565  */
566 Firesim.getASD = function(points, fct, fuelModel, index)
567 {
568     fuelModel = (fuelModel) ? fuelModel : "B1R4";
569 
570     $.ajax({
571         url: "determine_asd.php",
572         type: "POST",
573         data: {
574             file: "/home/svn/web/layers/fuelsModels/B1R4CORINEComplet.xml",
575             index: index,
576             coordinates: points
577         },
578         success: function(data) {
579             if (fct)
580                 fct(data);
581         }
582     });
583 };