//(function () { angular.module('MobileWebLogistics') .service('createReport', function () { var printServ = this; this.openBookmarks = function (toolbar) { toolbar.deactivate(); $("#drawTools div").removeClass("selected").removeClass("unselected"); if ($("#bookmarksMenu").hasClass("active")) { $("#bookmarksMenu").removeClass("active"); $("#openBookmarks").removeClass("active"); } else { $("#mapButtons > div").removeClass("active"); $("#mapDropdowns > div").removeClass("active"); $("#bookmarksMenu").addClass("active"); $("#openBookmarks").addClass("active"); } } this.exportList = function ($scope, $timeout) { var dataHeader = []; var dataField = []; if ($scope.queryLyr == 'pt') { if ($scope.csvHeaderPtField.length > 0) { for (var i = 0; i < $scope.csvHeaderPtField.length; i++) { dataHeader.push($scope.csvHeaderPtField[i][0]); dataField.push($scope.csvHeaderPtField[i][1]); } } } else { if ($scope.csvSResultField.length > 0) { for (var i = 0; i < $scope.csvSResultField.length; i++) { dataHeader.push($scope.csvSResultField[i][0]); dataField.push($scope.csvSResultField[i][1]); } } } var searchResultData = []; $scope.queryResults.forEach(function (list, index) { searchResultData[index] = []; for (var i = 0; i < dataField.length; i++) { searchResultData[index].push(list[dataField[i]]); } }); var csvContent = dataHeader.join(",") + "\n"; searchResultData.forEach(function (infoArray, index) { infoArray.forEach(function (value, index) { if (value) { value = '"' + value.toString() + '"'; // for commas in the owner field infoArray[index] = value; } }); dataString = infoArray.join(","); csvContent += dataString + "\n"; }); var blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); if (navigator.msSaveBlob) { // IE 10+ navigator.msSaveBlob(blob, "searchResults.csv") } else { var encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent); var link = document.createElement("a"); //console.log(encodedUri); link.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csvContent); link.setAttribute("href", encodedUri); link.setAttribute("download", "searchResults.csv"); //console.log(link); document.body.appendChild(link); //required in FF, optional for Chrome link.target = "_blank"; //required in FF, optional for Chrome link.download = 'searchResults.csv'; $timeout(function () { // We must reevaluate the value in case it was changed by a subsequent // watch handler in the digest. link.click(); }, 0, false); } } this.startDownload = function ($scope, format, $timeout) { if (format == 'pdf') { $("#pdfPreloaderContainer").addClass("active"); $("#reportBody").html($("#detail1 > div").html()); $("#reportBody > div > div").removeClass("col-md-3 col-md-4 col-md-6"); $("#reportBody h5").replaceWith( function () { return $("<p />", { html: $(this).html() }); }); var absolutePath = function (href) { var link = document.createElement("a"); link.href = href; return (link.protocol + "//" + link.host + link.pathname + link.search + link.hash); } if ($scope.thumbnailUrl === undefined) { var parcelUrl = ""; } else { var parcelUrl = $scope.thumbnailUrl.replace("Thumbnails", "Parcels"); parcelUrl += $scope.selectedParcel[$scope.imageUid] + '_1.jpg'; } if ($scope.propertyImg == 'true') { $("#report img").attr("src", parcelUrl).removeAttr('err-src').removeAttr('ng-src'); } $("#report hr").remove(); $("#report").attr("style", "position:static;top:0px"); if ($scope.customImgName == 'true' || $scope.customReportTblName == 'true' || $scope.customPdfReporte == 'true') { $scope.localCustom.createPDF($scope, parcelUrl); } else { printServ.createPDF($scope, parcelUrl); } } else if (format == 'csv') { var dataHeader = []; var dataField = []; if ($scope.csvHeaderField.length > 0) { for (var i = 0; i < $scope.csvHeaderField.length; i++) { dataHeader.push($scope.csvHeaderField[i][0]); dataField.push($scope.csvHeaderField[i][1]); } } var adjoinerData = []; $scope.adjoinerList.forEach(function (adjoiner, index) { adjoinerData[index] = []; for (var i = 0; i < dataField.length; i++) { adjoinerData[index].push(adjoiner[dataField[i]]); } }); //var csvContent = "data:text/csv;charset=utf-8,"; var csvContent = dataHeader.join(",") + "\n"; adjoinerData.forEach(function (infoArray, index) { infoArray.forEach(function (value, index) { if (value) { value = '"' + value.toString() + '"'; // for commas in the owner field infoArray[index] = value; } }); dataString = infoArray.join(","); csvContent += dataString + "\n"; }); var blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); if (navigator.msSaveBlob) { // IE 10+ navigator.msSaveBlob(blob, "adjoiners.csv") } else { var encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent); var link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", "adjoiners.csv"); document.body.appendChild(link); //required in FF, optional for Chrome // $scope.$apply(); link.target = "_blank"; //required in FF, optional for Chrome link.download = 'adjoiners.csv'; $timeout(function () { // We must reevaluate the value in case it was changed by a subsequent // watch handler in the digest. link.click(); }, 0, false); } } } var pdf, parcelImg, isParcelImg, parcelMap, imgwidth1, imgwidth2, imgwidth3; var imgheight1, imgheight2, imgheight3; var availSpace = 265; var defaultTop = 28; var page = 1; this.imageExists = function ($scope, url, callback) { //alert(url); var img = new Image(); img.setAttribute('crossOrigin', 'anonymous'); var parcelImgUrl1 = url.toString(); img.onload = function () { $scope.reportImages.push(img); callback(true); }; img.onerror = function () { callback(false); }; img.src = url; if (img.src.slice(-1) !== "?") { img.src = parcelImgUrl1 + "?"; //for chrome just in case } // alert(callback); return; } this.createPDF = function ($scope, parcelImgUrl) { //alert("bb"); if (parcelImgUrl !== null && parcelImgUrl !== "") { parcelImg = new Image(); parcelImg.setAttribute('crossOrigin', 'anonymous'); var parcelImgUrl1 = parcelImgUrl.toString(); parcelImg.onload = function () { isParcelImg = true; }; parcelImg.onerror = function () { isParcelImg = false; }; parcelImg.src = parcelImgUrl; parcelImg.src = parcelImgUrl1 + "?"; } else { var isParcelImg = false; } setTimeout(function () { var img1; pdf = new jsPDF('portrait', 'mm', 'letter', true); var margins = { top: 15, bottom: 60, //left: $scope.headerH + 5, left: 20, width: 520 }; //adding report printServ.addTable1($scope, isParcelImg); }, 500); } this.addHeader = function ($scope) { try { pdf.addImage('headerImg', 'PNG', 15, 8, 71.7 * 0.861, 22.49 * 0.861); } catch (err) { pdf.addImage($scope.headerData, 'PNG', 15, 8, 71.7 * 0.861, 22.49 * 0.861, 'headerImg'); } pdf.setFont("arial"); pdf.setTextColor(0, 0, 0); pdf.setFontSize(10); pdf.textEx($scope.pdfHeaderTxt1, 194, 18, 'right', 'middle'); pdf.textEx($scope.pdfHeaderTxt2, 193, 23, 'right', 'middle'); pdf.setLineWidth(0.4); pdf.setDrawColor(0, 0, 0); pdf.line(37, 25, 198, 25); } this.addFooter = function (pidtxt, pid, page) { pdf.setLineWidth(0.4); pdf.setDrawColor(220, 220, 220); pdf.line(15, 260, 198, 260); pdf.setFont("arial"); pdf.setTextColor(100, 100, 100); pdf.setFontSize(10); if (pidtxt.trim().length > 0) { pdf.text(16, 265, pidtxt + pid); } pdf.text(183, 265, page + ' | Page'); } this.getReportImages = function ($scope, pid, isParcelImg) { if ($scope.propertyImg != 'false') { if (pid == 1 && isParcelImg == true) { $scope.reportImages.push(parcelImg); } if (isParcelImg == true) { //==check and add additional images var nextPid = parseInt(pid) + 1; var moreImgUrl = parcelImg.src.replace('_1.jpg', '_' + nextPid + '.jpg'); printServ.imageExists($scope, moreImgUrl, function (exists) { if (exists) { printServ.getReportImages($scope, pid + 1, isParcelImg) } else { printServ.addImages($scope); } //==end of check and add additional images }); } else { printServ.addImages($scope); } } else { printServ.addImages($scope); } } this.addImages = function ($scope) { if ($scope.propertyImg == 'false') { isParcelImg = false; } var imgLoc; var j; if ($scope.reportImages.length > 0) { printServ.addFooter($scope.parcelpdfID[0], $scope.selectedParcel[$scope.parcelpdfID[1]], page); page += 1; imgLoc = 30; pdf.addPage(); printServ.addHeader($scope); } for (j = 0; j < $scope.reportImages.length; j++) { var imgW = $scope.reportImages[j].width / ($scope.reportImages[j].width / 140); var imgH = $scope.reportImages[j].height / ($scope.reportImages[j].width / 140); if (imgLoc + imgH > availSpace) { printServ.addFooter($scope.parcelpdfID[0], $scope.selectedParcel[$scope.parcelpdfID[1]], page); page += 1; imgLoc = 30; pdf.addPage(); printServ.addHeader($scope); } pdf.addImage($scope.reportImages[j], 'JPEG', 35, imgLoc, imgW, imgH, 'house' + j); imgLoc = imgLoc + imgH + 10; if ($scope.multipleReportImages != 'true') { j = 1000; } } printServ.addFooter($scope.parcelpdfID[0], $scope.selectedParcel[$scope.parcelpdfID[1]], page); // add a new page with the parcel map image (if enabled, otherwise will just save and return) printServ.addParcelMap($scope); page = 1; } var tblNum = 1; this.addTable1 = function ($scope, isParcelImg) { printServ.addHeader($scope); pdf.setFont("arial"); pdf.setTextColor(80, 80, 80); pdf.setFontSize(16); pdf.text(17, 42, $("#propertyAddr").html()); html2canvas($("#reportBody > #reportTbl_1"), { onrendered: function (canvas1) { var imgData1 = canvas1.toDataURL('image/png'); imgwidth1 = canvas1.width * 0.227; // This will print out the width. imgheight1 = canvas1.height * 0.23; pdf.addImage(imgData1, 'PNG', 16, 45, imgwidth1, imgheight1); nextTblLoc = imgheight1 + 45; tblNum = 2; if (tblNum > $scope.numOfTable) { $scope.reportImages = []; printServ.getReportImages($scope, 1, isParcelImg); } else { printServ.addAdditionalTable($scope, isParcelImg); } } }); } this.addAdditionalTable = function ($scope, isParcelImg) { html2canvas($("#reportBody > #reportTbl_" + tblNum), { onrendered: function (canvas2) { var imgData2 = canvas2.toDataURL('image/png'); imgwidth2 = canvas2.width * 0.227; // This will print out the width. imgheight2 = canvas2.height * 0.23; if (nextTblLoc + imgheight2 > availSpace) { //add page and nextTblLoc=35 printServ.addFooter($scope.parcelpdfID[0], $scope.selectedParcel[$scope.parcelpdfID[1]], page); page += 1; pdf.addPage(); printServ.addHeader($scope); nextTblLoc = defaultTop; pdf.addImage(imgData2, 'PNG', 16, nextTblLoc, imgwidth2, imgheight2); nextTblLoc += imgheight2; } else { pdf.addImage(imgData2, 'PNG', 16, nextTblLoc, imgwidth2, imgheight2); nextTblLoc = nextTblLoc + imgheight2; } tblNum += 1; if (tblNum > $scope.numOfTable) { $scope.reportImages = []; printServ.getReportImages($scope, 1, isParcelImg); } else { printServ.addAdditionalTable($scope, isParcelImg); } } }); } this.printComplete = function (result, $scope) { console.log(result.url); setTimeout(function () { printServ.addMap($scope, result.url); }, 2000); } this.printError = function ($scope, error) { if ($scope.pcount == 0) { $scope.printTask.execute($scope.params, printComplete, printError); } $scope.pcount = $scope.pcount + 1; if ($scope.pcount > 1) { $("#printBtn i").removeClass('glyphicon glyphicon-cog glyphicon-cog-animate').addClass('glyphicon glyphicon-print'); $("#printBtn").attr('disabled', false); pdfUrl = ""; } } this.execPrintMap = function ($scope) { var selectList = document.getElementById("printSize"); var template = selectList.options[selectList.selectedIndex].value; var mapTitle = $("#mapTitle").val(); $scope.params.map = $scope.map; var ptemp = new $scope.PrintTemplate(); //params.SpatialReference = new SpatialReference({ wkid: 3857 }); $scope.params.SpatialReference = new $scope.SpatialReference({ wkid: 102100 }); ptemp.format = "PNG32"; ptemp.layout = template; //ptemp.layout = "MAP_ONLY"; /*ptemp.layoutOptions = { titleText: mapTitle, legendLayers: [] // empty array means no legend };*/ ptemp.layoutOptions = { titleText: mapTitle }; ptemp.exportOptions = { //width: 1200, //height: 800, dpi: 120 }; ptemp.showAttribution = false; ptemp.showLabels = true; $scope.params.template = ptemp; //$scope.wmsLayer.opacity= $("#overlayTransparency").val()/100; $scope.dmsLayer.opacity = $("#overlayTransparency").val() / 100; var printurl = $scope.printer.url; $scope.printTask = new $scope.PrintTask(printurl); //this.printTask = new PrintTask(this.printTaskURL, {async: true}); $scope.printTask.execute($scope.params, printServ.printComplete, printServ.printError); } this.createMapImage = function ($scope) { $scope.execPrintMap(); } this.addParcelMap = function ($scope) { // FIXME: this completes the pdf workflow...but this should not be here or structured this way - done in the interest of time var _savePdf = function () { pdf.save('Parcel_report.pdf'); $("#pdfPreloaderContainer").removeClass("active"); }; // method to write an error message on the page if getting image fails var _insertErrorText = function () { pdf.setTextColor(255, 0, 0); pdf.setFontSize(20); pdf.text(35, 50, "Unable to load parcel map image"); _savePdf(); }; // reset the bool flag for the parcel map loading if parcel map is enabled in the $scope vars // FIXME: this is part of a poor workaround to the pdf creation workflow not waiting for images to load if ($scope.enableCreateReportParcelMap !== "true") { return _savePdf(); }; var width = 800, height = 800; // add new page for the parcel map pdf.addPage(); printServ.addHeader($scope); // canvas & its context to load data url from // FIXME: add call to remove the canvas? var canvas = document.createElement("CANVAS"); // adjust the dimensions of the canvas, otherwise it will clip the img if the img is larger! canvas.width = width; canvas.height = height; var context = canvas.getContext("2d"); // source url for the image var imageSrcUrl = ""; // image object for grabbing and inserting map image var img = new Image(); img.crossOrigin = "anonymous"; img.onerror = function (e) { console.error('createReport.addParcelMap: loading parcel image failed for url "' + img.src + '"'); _insertErrorText(); }; img.onload = function () { // attempt to load the image into the pdf--insert an error message upon failure try { // paint img onto a canvas & get data URL for canvas context.drawImage(img, 0, 0, width, height); // XXX: canvas.toDataURL METHOD WILL FAIL TO PRODUCE A JPEG URL USING 'image/jpg', PRODUCES PNG INSTEAD BUT // DOES NOT THROW ANY ERRORS var dataUrl = context.canvas.toDataURL('image/jpeg'); // XXX: jsPDF.addImage SILENTLY COMPLAINS ABOUT 'JPG' VS 'JPEG' (SEE https://parall.ax/products/jspdf) pdf.addImage(dataUrl, 'JPEG', 16, 45, 160, 160); _savePdf(); } catch (e) { console.error('createReport.addParcelMap: inserting parcel image into PDF failed :' + e); _insertErrorText(); } }; // copied logic from printMap.js & zoomTo.js to print map of the parcel var ptemp = new esri.tasks.PrintTemplate(); ptemp.format = "jpg"; ptemp.layout = "MAP_ONLY"; var unit = 'Mile'; if ($scope.isDynamicUnit == 'true') { if ($scope.map.getScale() < $scope.dynamicUnit[1]) { unit = 'Feet' } } ptemp.layoutOptions = { titleText: mapTitle, scalebarUnit: unit, legendLayers: [] // empty array means no legend }; ptemp.exportOptions = { width: width, height: height, dpi: 120 }; ptemp.showAttribution = false; ptemp.showLabels = true; var params = new esri.tasks.PrintParameters(); params.SpatialReference = new esri.SpatialReference({ wkid: 102100 }); params.template = ptemp; params.map = $scope.map; // get the extent of the parcel selected, set the map to that extent var parcelExtent = $scope.selectedParcel.geometry.getExtent().expand(1.25); var mapExtentDeferred = params.map.setExtent(parcelExtent); mapExtentDeferred.then(function (value) { // when the process is complete of zooming the map, continue with the print task var printTask = new esri.tasks.PrintTask($scope.printer.url); // execute print job printTask.execute(params, // if successful insert result into PDF function (successResult) { img.src = successResult.url; }, // if failed show an error message function (failureResult) { console.error("createReport.js: Unable to get parcel map image with URL \"" + $scope.printer.url + "\" -> " + failureResult); _insertErrorText(); } ); }, function (err) { // if it errors exit console.error("Map extent change error: " + err); _insertErrorText(); }); page += 1; printServ.addFooter($scope.parcelpdfID[0], $scope.selectedParcel[$scope.parcelpdfID[1]], page); } }); //})();