1 /** 2 * @fileOverview 3 * Copyright (c) 2013 Regione Autonoma della Sardegna 4 * Published under the GPL license.<br> 5 * See <a href="https://sardegnageoportale.it/webgis/license.txt">https://sardegnageoportale.it/webgis/license.txt</a> 6 * for the full text of the license. 7 * @version 0.1 8 */ 9 10 /* 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 /** 26 * @namespace framework.data 27 */ 28 Ext.namespace("framework.data"); 29 30 /** 31 * XSL reader for routing service of Regione Sardegna 32 * @name_ RoutingOpenLS_XLSReader 33 * @class XSL reader for rounting service of Regione Sardegna 34 * @extends Ext.data.XmlReader - See <a href="http://dev.sencha.com/deploy/ext-3.3.1/docs?class=Ext.data.XmlReader">Ext.data.XmlReader</a> 35 * @constructor 36 * @param {object} meta 37 * @param {Ext.data.Record} recordType 38 */ 39 framework.data.RoutingOpenLS_XLSReader = function(meta, recordType) { 40 meta = meta || {}; 41 42 43 Ext.applyIf(meta, { 44 idProperty: meta.idProperty || meta.idPath || meta.id, 45 successProperty: meta.successProperty || meta.success 46 }); 47 48 framework.data.RoutingOpenLS_XLSReader.superclass.constructor.call(this, meta, recordType || meta.fields); 49 }; 50 51 Ext.extend(framework.data.RoutingOpenLS_XLSReader, Ext.data.XmlReader, 52 /** 53 * @lends framework.data.RoutingOpenLS_XLSReader.prototype 54 */ 55 { 56 57 /** This method is only used by a DataProxy which has retrieved data from a remote server. 58 * Create responseXML if the responseText is a XML format 59 * @public 60 * @param {Object} response The XHR object which contains the parsed XML document. 61 * The response is expected to contain a method called 'responseXML' that returns an XML document object. 62 * @returns {Object} records A data block which is used by an {@link Ext.data.Store} as 63 * a cache of Ext.data.Records. 64 */ 65 read : function(response){ 66 if(!response.responseXML){ 67 var text = response.responseText; 68 try { // code for IE 69 var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 70 xmlDoc.async = "false"; 71 xmlDoc.loadXML(text); 72 response.responseXML = xmlDoc; 73 }catch(error) { // code for Mozilla, Firefox, Opera, etc. 74 try { 75 var parser = new DOMParser(); 76 var xmlDoc = parser.parseFromString(text,"text/xml"); 77 response.responseXML = xmlDoc; 78 }catch(error) { 79 alert(error.message); 80 return; 81 } 82 } 83 } 84 var doc = response.responseXML; 85 if(!doc) { 86 throw {message: "XmlReader.read: XML Document not available"}; 87 } 88 return this.readRecords(doc); 89 }, 90 91 /** get a content node by a xml tag name 92 * @public 93 * @param {string}format xml reader and writer 94 * @param {string} text html text 95 * @param {string} node xml node 96 * @param {string} tagname tag from where extract data 97 * @param {string} sep separator character 98 * @returns {object} html text 99 */ 100 addOptXlsTextAddress: function(format, text, node, tagname, sep) { 101 var elms = format.getElementsByTagNameNS(node, "http://www.opengis.net/xls", tagname); 102 if (elms) { 103 Ext.each(elms, function(elm, index) { 104 var str = format.getChildValue(elm); 105 /* if (str) { 106 text = text + sep + str; 107 }*/ 108 if (tagname === "Place") { 109 var attvaluetype = elm.getAttribute('type'); 110 if (attvaluetype === 'Municipality') 111 text = text + sep + '<b>' + str + '</b>'; 112 else if (attvaluetype === 'CountrySecondarySubdivision') 113 text = text + sep + '(' + str + ')'; 114 } 115 else if (tagname === "Street") { 116 var attvalueon = elm.getAttribute('officialName'); 117 text = text + sep + attvalueon; 118 } 119 }); 120 } 121 122 return text; 123 }, 124 /** get 'Text' info from a xml segment 125 * 126 * @public 127 * @function 128 * @param {string}format 129 * @param {string} text 130 * @param {string} node 131 * @param {string} tagname 132 * @param {string} sep 133 * @returns {object} 134 */ 135 136 137 addOptXlsText: function(format, text, node, tagname, sep) { 138 139 var elms = format.getElementsByTagNameNS(node, "http://www.opengis.net/xls", tagname); 140 if (elms) { 141 Ext.each(elms, function(elm, index) { 142 var str = elm.getAttribute('value'); 143 if (tagname === "POIInfo") { 144 var attvaluename = elm.getAttribute('name'); 145 if (attvaluename === 'Alias') { 146 text = text + sep + '<b>' + str + '</b>'; 147 } 148 else if (attvaluename === 'NomeComune') { 149 text = text + sep + ' (' + str + ')'; 150 } 151 } 152 }); 153 } 154 155 return text; 156 }, 157 158 /** get 'POINumResults' info from a xml segment 159 * @public 160 * @param {string}format 161 * @param {string} text 162 * @param {string} node 163 * @param {string} tagname 164 * @param {string} sep 165 * @returns {object} 166 */ 167 addOptXlsPOINumResults: function(format, numresult, node, tagname, sep) { 168 var elms = format.getElementsByTagNameNS(node, "http://www.opengis.net/xls", tagname); 169 if (elms) { 170 Ext.each(elms, function(elm, index) { 171 var str = elm.getAttribute('value'); 172 if (tagname === "POIInfo") { 173 var attvaluename = elm.getAttribute('name'); 174 if (attvaluename === 'POINumResults') { 175 numresult = str; 176 } 177 } 178 }); 179 } 180 181 return numresult; 182 }, 183 184 /** get 'POIType' info from a xml segment 185 * @public 186 * @param {string}format 187 * @param {string} text 188 * @param {string} node 189 * @param {string} tagname 190 * @param {string} sep 191 * @returns {object} 192 */ 193 194 addOptXlsPOIType: function(format, type, node, tagname, sep) { 195 var elms = format.getElementsByTagNameNS(node, "http://www.opengis.net/xls", tagname); 196 if (elms) { 197 Ext.each(elms, function(elm, index) { 198 var str = elm.getAttribute('value'); 199 if (tagname === "POIInfo") { 200 var attvaluename = elm.getAttribute('name'); 201 if (attvaluename === 'NomeTipo') { 202 type = str; 203 } 204 } 205 }); 206 } 207 208 return type; 209 }, 210 211 /** fill up a object with query result 212 * @public 213 * @param {string} doc 214 * @returns {object} 215 */ 216 readRecords: function(doc) { 217 218 this.xmlData = doc; 219 220 var root = doc.documentElement || doc; 221 222 var records = this.extractData(root); 223 224 return { 225 success: true, 226 records: records, 227 totalRecords: records[0].data.numresult 228 }; 229 }, 230 231 calculateTime: function(time) { 232 233 var totalTime = []; 234 235 totalTime["seconds"] = time.substring(time.lastIndexOf('M')+1,time.lastIndexOf('S')); 236 totalTime["minutes"] = time.substring(time.lastIndexOf('H')+1,time.lastIndexOf('M')); 237 totalTime["hours"] = time.substring(time.lastIndexOf('T')+1,time.lastIndexOf('H')); 238 if (totalTime["seconds"] == '') 239 totalTime["seconds"] = 0; 240 if (totalTime["minutes"] == '') 241 totalTime["minutes"] = 0; 242 if (totalTime["hours"] == '') 243 totalTime["hours"] = 0; 244 245 return totalTime; 246 }, 247 248 /** create array of record extracting data from a xml 249 * @public create records from xml content 250 * @param {string} root 251 * @returns {array} record 252 */ 253 extractData: function(root) { 254 var opts = { 255 /** 256 * Property: namespaces 257 * {Object} Mapping of namespace aliases to namespace URIs. 258 */ 259 namespaces: { 260 gml: "http://www.opengis.net/gml", 261 xls: "http://www.opengis.net/xls" 262 } 263 }; 264 265 var records = []; 266 var records_poi = []; 267 var records_steps = []; 268 var format = new OpenLayers.Format.XML(opts); 269 270 // Create record for each routing or alternative point 271 var recordType = Ext.data.Record.create([ 272 {name: 'totalTime'}, 273 {name: 'totalDistance_uom'}, 274 {name: 'totalDistance_value', type: "number"}, 275 {name: 'totalBoundingBox'}, 276 {name: 'routeGeometry'}, 277 {name: 'duration'}, 278 {name: 'description'}, 279 {name: 'instruction'}, 280 {name: 'distance_uom'}, 281 {name: 'distance_value', type: "number"}, 282 {name: "routeInstructionGeometry"}, 283 {name: "boundingBox"}, 284 {name: "poi_result_text"}, 285 {name: "poi_result_xml"}, 286 {name: "poi_result_type"}, 287 {name: "poi_result_lon", type: "number"}, 288 {name: "poi_result_lat", type: "number"}, 289 {name: "msg_error"} 290 ]); 291 var reader = this; 292 293 /** 294 * Verifica partenza, tappe e arrivo 295 */ 296 297 // calcolo numero di tappe 298 var points = 2; 299 points += root.getElementsByTagName('ViaPoint').length; 300 301 var wayPointEncodeResponseList = root.getElementsByTagName('WayPointEncodeResponseList'); 302 303 var type = null; 304 var id = 0; 305 var result_poi = false; 306 307 Ext.each(wayPointEncodeResponseList, function(list, index) { 308 309 /** 310 * Verifica punto di partenza, tappe o punto di arrivo 311 */ 312 313 if (index === 0) { 314 type = 'start'; 315 } 316 else if (index === (points-1)){ 317 type = 'stop'; 318 } 319 else if (index === 1) { 320 type = 'via1'; 321 } 322 else 323 type = 'via2'; 324 325 /** 326 * Verifica se ci sono più risultati per punto di partenza o punto di arrivo 327 */ 328 329 var num_list = list.getAttribute('numberOfEncodedWayPoints'); 330 331 if (num_list > 1) // caso di più risultati 332 result_poi = true; 333 334 /** 335 * Controllo caso indirizzi 336 */ 337 338 var geocodedAddress = format.getElementsByTagNameNS(list, "http://www.opengis.net/xls", 'GeocodedAddress'); 339 340 if (geocodedAddress.length > 0) { 341 342 Ext.each(geocodedAddress, function(address, index) { 343 344 var pos = format.getElementsByTagNameNS(address, "http://www.opengis.net/gml", 'pos'); 345 var xy = ''; 346 if (pos && pos[0]) { 347 xy = format.getChildValue(pos[0]); 348 } 349 350 var xyArr = xy.split(' '); 351 352 var text = ''; 353 354 text = reader.addOptXlsTextAddress(format, text, address, 'Street', ''); 355 text = reader.addOptXlsTextAddress(format, text, address, 'Place', ' '); 356 357 var xml = format.getElementsByTagNameNS(address, "http://www.opengis.net/xls", 'Address'); 358 xml = xml[0].outerHTML; 359 360 361 var values = { 362 poi_result_lon: parseFloat(xyArr[0]), 363 poi_result_lat: parseFloat(xyArr[1]), 364 poi_result_text: text, 365 poi_result_xml: xml, 366 poi_result_type: type 367 }; 368 var record = new recordType(values, id); 369 if (num_list > 1) records_poi.push(record); 370 else records_steps.push(record); 371 id++; 372 373 }, this); 374 375 } 376 377 /** 378 * Controllo caso toponimi 379 */ 380 381 var poi = format.getElementsByTagNameNS(list, "http://www.opengis.net/xls", 'POI'); 382 383 var encodeWayPoint = list.getElementsByTagName('EncodedWayPoint'); 384 385 if (poi.length > 0){ 386 387 Ext.each(poi, function(point, index) { 388 var pos = format.getElementsByTagNameNS(point, "http://www.opengis.net/gml", 'pos'); 389 var xy = ''; 390 if (pos && pos[0]) { 391 xy = format.getChildValue(pos[0]); 392 } 393 394 395 var xyArr = xy.split(' '); 396 397 var text = ''; 398 var numresult = ''; 399 var type_poi = ''; 400 401 text = reader.addOptXlsText(format, text, point, 'POIInfo', ''); 402 type_poi = reader.addOptXlsPOIType(format, type, point, 'POIInfo', ''); 403 404 var xml = format.getElementsByTagNameNS(encodeWayPoint[index], "http://www.opengis.net/xls", 'POI'); 405 xml = xml[0].outerHTML; 406 407 var values = { 408 poi_result_lon: parseFloat(xyArr[0]), 409 poi_result_lat: parseFloat(xyArr[1]), 410 poi_result_text: text, 411 poi_result_xml: xml, 412 poi_result_type: type 413 }; 414 var record = new recordType(values, index); 415 if (num_list > 1) records_poi.push(record); 416 else records_steps.push(record); 417 id++; 418 }); 419 420 } 421 422 423 }, this); 424 425 var routeSummary = format.getElementsByTagNameNS(root, "http://www.opengis.net/xls", 'RouteSummary'); 426 427 if (result_poi) { 428 return records_poi; 429 } 430 else if (routeSummary.length > 0) { 431 432 433 var routeGeometry = format.getElementsByTagNameNS(root, "http://www.opengis.net/xls", 'RouteGeometry'); 434 var routeInstruction = format.getElementsByTagNameNS(root, "http://www.opengis.net/xls", 'RouteInstruction'); 435 436 437 var totalTimeArray = []; 438 var totalDistance_uom = ''; 439 var totalDistance_value = 0; 440 var totalBoundingBox = []; 441 442 443 Ext.each(routeSummary, function(routeSummary, index) { 444 445 var totalTimeTag = format.getElementsByTagNameNS(routeSummary, "http://www.opengis.net/xls", 'TotalTime'); 446 if (totalTimeTag) { 447 Ext.each(totalTimeTag, function(istr, index) { 448 totalTimeArray = this.calculateTime(format.getChildValue(istr)); 449 },this); 450 } 451 452 var totalDistance = format.getElementsByTagNameNS(routeSummary, "http://www.opengis.net/xls", 'TotalDistance'); 453 if (totalDistance) { 454 Ext.each(totalDistance, function(dist, index) { 455 totalDistance_uom = dist.getAttribute('uom'); 456 totalDistance_value = dist.getAttribute('value'); 457 }); 458 } 459 460 var totalBoundingBoxTag = format.getElementsByTagNameNS(routeSummary, "http://www.opengis.net/xls", 'BoundingBox'); 461 if (totalBoundingBoxTag) { 462 Ext.each(totalBoundingBoxTag, function(bb, index) { 463 var posBoundingBox = format.getElementsByTagNameNS(bb, "http://www.opengis.net/gml", 'pos'); 464 465 Ext.each(posBoundingBox, function(pos, index) { 466 //routeInstructionGeometry += pos.childNodes[0].data; 467 var coordinates = []; 468 var coordinates = pos.childNodes[0].data.split(" ").map(Number); 469 totalBoundingBox.push(coordinates); 470 }); 471 472 473 }); 474 } 475 476 },this); 477 478 var totalRouteGeometry = []; 479 480 Ext.each(routeGeometry, function(routeGeometry, index) { 481 482 var lineString = format.getElementsByTagNameNS(routeGeometry, "http://www.opengis.net/gml", 'LineString'); 483 if (lineString) { 484 Ext.each(lineString, function(line, index) { 485 var posLineString = format.getElementsByTagNameNS(line, "http://www.opengis.net/gml", 'pos'); 486 Ext.each(posLineString, function(pos, index) { 487 //routeInstructionGeometry += pos.childNodes[0].data; 488 var coordinates = []; 489 var coordinates = pos.childNodes[0].data.split(" ").map(Number); 490 totalRouteGeometry.push(coordinates); 491 }); 492 493 }); 494 } 495 496 }); 497 498 var POIRouteGeometry = []; 499 500 501 // INSERIMENTO PUNTO DI PARTENZA 502 503 var coordinates = [records_steps[0].data.poi_result_lon,records_steps[0].data.poi_result_lat]; 504 var routeInstructionGeometry = []; 505 routeInstructionGeometry.push(coordinates); 506 507 var values = { 508 totalTime: totalTimeArray, 509 totalDistance_uom: totalDistance_uom, 510 totalDistance_value: totalDistance_value, 511 totalRouteGeometry: totalRouteGeometry, 512 totalBoundingBox: totalBoundingBox, 513 instruction: records_steps[0].data.poi_result_text, 514 routeInstructionGeometry: routeInstructionGeometry, 515 poi_result_type: records_steps[0].data.poi_result_type 516 }; 517 var record = new recordType(values, 0); 518 records.push(record); 519 520 var via1 = true; 521 var via2 = true; 522 var num = 1; 523 524 525 526 Ext.each(routeInstruction, function(routeInstruction, index) { 527 528 var description = routeInstruction.getAttribute('description'); 529 530 // INSERIMENTO STEP 1 531 532 if ((description == "step2" || description == "step2-fromPOI") && via1) { 533 534 var coordinates = [records_steps[num].data.poi_result_lon,records_steps[num].data.poi_result_lat]; 535 var routeInstructionGeometry = []; 536 routeInstructionGeometry.push(coordinates); 537 538 var values = { 539 totalTime: totalTimeArray, 540 totalDistance_uom: totalDistance_uom, 541 totalDistance_value: totalDistance_value, 542 totalRouteGeometry: totalRouteGeometry, 543 totalBoundingBox: totalBoundingBox, 544 instruction: records_steps[num].data.poi_result_text, 545 routeInstructionGeometry: routeInstructionGeometry, 546 poi_result_type: records_steps[num].data.poi_result_type 547 }; 548 var idx = index + num; 549 var record = new recordType(values, idx); 550 records.push(record); 551 552 via1 = false; 553 num++; 554 555 } 556 557 // INSERIMENTO STEP 2 558 559 if ((description == "step3" || description == "step3-fromPOI") && via2) { 560 561 var coordinates = [records_steps[num].data.poi_result_lon,records_steps[num].data.poi_result_lat]; 562 var routeInstructionGeometry = []; 563 routeInstructionGeometry.push(coordinates); 564 565 var values = { 566 totalTime: totalTimeArray, 567 totalDistance_uom: totalDistance_uom, 568 totalDistance_value: totalDistance_value, 569 totalRouteGeometry: totalRouteGeometry, 570 totalBoundingBox: totalBoundingBox, 571 instruction: records_steps[num].data.poi_result_text, 572 routeInstructionGeometry: routeInstructionGeometry, 573 poi_result_type: records_steps[num].data.poi_result_type 574 }; 575 var idx = index + num ; 576 var record = new recordType(values, idx); 577 records.push(record); 578 579 via2 = false; 580 num++; 581 582 } 583 584 585 var durationArray = []; 586 var durationArray = this.calculateTime(routeInstruction.getAttribute('duration')); 587 588 589 var tagInstruction = format.getElementsByTagNameNS(routeInstruction, "http://www.opengis.net/xls", 'Instruction'); 590 var instruction = ''; 591 if (tagInstruction) { 592 Ext.each(tagInstruction, function(istr, index) { 593 instruction = format.getChildValue(istr); 594 }); 595 } 596 var distance = format.getElementsByTagNameNS(routeInstruction, "http://www.opengis.net/xls", 'distance'); 597 var distance_uom = ''; 598 var distance_value = 0; 599 if (distance) { 600 Ext.each(distance, function(dist, index) { 601 distance_uom = dist.getAttribute('uom'); 602 distance_value = dist.getAttribute('value'); 603 }); 604 } 605 var lineString = format.getElementsByTagNameNS(routeInstruction, "http://www.opengis.net/gml", 'LineString'); 606 var routeInstructionGeometry = ''; 607 if (lineString) { 608 Ext.each(lineString, function(line, index) { 609 var posLineString = format.getElementsByTagNameNS(line, "http://www.opengis.net/gml", 'pos'); 610 routeInstructionGeometry = []; 611 Ext.each(posLineString, function(pos, index) { 612 var coordinates = []; 613 var coordinates = pos.childNodes[0].data.split(" ").map(Number); 614 routeInstructionGeometry.push(coordinates); 615 }); 616 }); 617 } 618 var boundingBoxTag = format.getElementsByTagNameNS(routeInstruction, "http://www.opengis.net/xls", 'BoundingBox'); 619 var boundingBox = ''; 620 if (boundingBoxTag) { 621 Ext.each(boundingBoxTag, function(bb, index) { 622 var posBoundingBox = format.getElementsByTagNameNS(bb, "http://www.opengis.net/gml", 'pos'); 623 //boundingBox = posBoundingBox; 624 625 boundingBox = []; 626 Ext.each(posBoundingBox, function(pos, index) { 627 var coordinates = []; 628 var coordinates = pos.childNodes[0].data.split(" ").map(Number); 629 boundingBox.push(coordinates); 630 }); 631 632 633 }); 634 } 635 636 var values = { 637 totalTime: totalTimeArray, 638 totalDistance_uom: totalDistance_uom, 639 totalDistance_value: totalDistance_value, 640 totalRouteGeometry: totalRouteGeometry, 641 totalBoundingBox: totalBoundingBox, 642 duration: durationArray, 643 description: description, 644 instruction: instruction, 645 distance_uom: distance_uom, 646 distance_value: distance_value, 647 routeInstructionGeometry: routeInstructionGeometry, 648 boundingBox: boundingBox 649 }; 650 var idx = index + num ; 651 var record = new recordType(values, idx); 652 records.push(record); 653 },this); 654 655 656 // INSERIMENTO PUNTO DI ARRIVO 657 658 var coordinates = [records_steps[num].data.poi_result_lon,records_steps[num].data.poi_result_lat]; 659 var routeInstructionGeometry = []; 660 routeInstructionGeometry.push(coordinates); 661 662 var values = { 663 totalTime: totalTimeArray, 664 totalDistance_uom: totalDistance_uom, 665 totalDistance_value: totalDistance_value, 666 totalRouteGeometry: totalRouteGeometry, 667 totalBoundingBox: totalBoundingBox, 668 instruction: records_steps[num].data.poi_result_text, 669 routeInstructionGeometry: routeInstructionGeometry, 670 poi_result_type: records_steps[num].data.poi_result_type 671 }; 672 var idx = routeInstruction.length + num ; 673 var record = new recordType(values, idx); 674 records.push(record); 675 676 677 return records; 678 679 } 680 else { 681 /** 682 * 1: result not found 683 */ 684 var values = { 685 msg_error: 1 686 }; 687 var record = new recordType(values, 0); 688 records.push(record); 689 return records; 690 } 691 692 } 693 694 695 });