FPDF print MultiCell() adjacently - fpdf

I've googled around and found this question very common but I can't seem to find a proper and direct answer. I'm using FPDF and I want to generate tables using MultiCell() since I need the line break property of it. Tried Cell() but it can't read the line break.
$col1="PILOT REMARKS\n\n";
$pdf->MultiCell(189, 10, $col1, 1, 1);
$col2="Pilot's Name and Signature\n".$name;
$pdf->MultiCell(63, 10, $col2, 1);
$pdf->Ln(0);
$col3="Date Prepared\n".$date;
$pdf->MultiCell(63, 10, $col3, 1);
But I can't generate it properly 'cause MultiCell() stacks the result. How can I achieve having MultiCell() printed adjacently with each other in a most simple and easy way?
Found this similar question but it doesn't provide a clear answer. Any help will be appreciated. Thanks in advance.

Try storing the X and Y co-ordinates and then setting them after the write
$x = $pdf->GetX();
$y = $pdf->GetY();
$col1="PILOT REMARKS\n\n";
$pdf->MultiCell(189, 10, $col1, 1, 1);
$pdf->SetXY($x + 189, $y);
$col2="Pilot's Name and Signature\n".$name;
$pdf->MultiCell(63, 10, $col2, 1);
$pdf->Ln(0);
$col3="Date Prepared\n".$date;
$pdf->MultiCell(63, 10, $col3, 1);

Just to add to Danny's answer. I like keeping the Width of each column stored and then use that when executing the SetXY method.
Example:
$x = $this->x;
$y = $this->y;
$push_right = 0;
$this->MultiCell($w = 100,3,"Column\r\nNumber 1",1,'C',1);
$push_right += $w;
$this->SetXY($x + $push_right, $y);
$this->MultiCell($w = 60,3,"Column\r\nNumber 2",1,'C',1);
$push_right += $w;
$this->SetXY($x + $push_right, $y);
$this->MultiCell(0,3,"Column 3\r\nFilling in the Rest",1,'C',1);

You can use SetXY(x,y) function to set cursor in pdf .
$pdf->SetXY(x,y);
Set cursor to print data in pdf
Where x is x-axis value and y is y-axis value

None of these worked for me. I had to SetXY before each element (for some reason it's reseting to the start of the multicell after write of any element). So before each and every element, manually SetXY.

use $pdf->Ln(10);
with $pdf->cell();
Example:
$pdf->cell(100,10,"your content");
$pdf->Ln(10);

Related

Get Row and Column number from "ThisComponent.CurrentSelection" in libreoffice calc basic

I have this code where I can get which one is the current selected cell and use it to modify its value:
theSelection = ThisComponent.CurrentSelection
theSelection.setString("some value")
Now I want to move to the next column to the right, if it was Microsoft excel VBA I could just use something like theSelection.Offset(0,1) but that's not the case. So I'm doing some workarounds of course:
nextCell = oActiveSheet.getCellByPosition( ???currentColumn + 1, ???currentRow)
ThisComponent.CurrentController.select( nextCell )
I just want to know the simplest way to replace these ??? to the actual values of the theSelection var to move to the next column to the right.
I also tried this:
nextCell = oActiveSheet.getCellByPosition( column() + 1, row())
But I don't know why it is always returning column() = 1 and row() = 1 in regardless of which is the value of the CurrentSelection. Thanks in advance for the help.
Get the cell address.
Sub ChangeAndThenGoToCellToRightOfSelection
oActiveSheet = ThisComponent.getCurrentController().getActiveSheet()
oSels = ThisComponent.getCurrentSelection()
If oSels.supportsService("com.sun.star.sheet.SheetCell") Then
'A single cell is selected.
oSels.setString("some value")
address = oSels.getCellAddress()
nextCell = oActiveSheet.getCellByPosition(address.Column + 1, address.Row)
ThisComponent.CurrentController.select(nextCell)
End If
End Sub
To see what an object can do, use an introspection tool such as XrayTool or MRI.

How to convert PDL image to GdkPixbuf

I'm trying to display a graph generated by PDL (using PLplot) inside a Gtk3 app. When I try the following code, I see two problems:
$pdlImg isn't a GdkPixbuf so new_from_pixbuf() doesn't work.
$pdlImg appears to be empty as because the error message prints out the 10x10x3 array as a string and they're all zeroes.
Code:
#!/usr/bin/perl -w
use strict;
use PDL;
use PDL::Graphics::PLplot;
use Gtk3 -init;
my $pdlImg = zeroes(byte, 10, 10, 3);
my $pl = PDL::Graphics::PLplot->new(DEV => 'mem', MEM => $pdlImg);
my $x = sequence(10);
my $y = $x**2;
$pl->xyplot($x, $y);
$pl->close;
my $win = Gtk3::Window->new;
my $img = Gtk3::Image->new_from_pixbuf($pdlImg);
$win->add($img);
$win->show_all;
Gtk3::main();
To answer your first question, you are having PLplot put the plot into a piddle that is 10 pixels wide and 10 pixels high. I'm not sure if you're just going to get one corner of the normal plot in that case, or if you're getting the whole plot sampled into those 10x10 pixels. But in either case it's no surprise that $pdlImg is entirely zeroes. Try passing in a piddle with larger size (perhaps 1000, 1000, 3), or perhaps even using MEM => $pdlImg=null when you create the PLplot plot object.
I can't help with your second question, I have no experience with Gtk3, sorry.

How to read elevation from USGS NED DEM GridFloat file in Perl

I have downloaded a large set of GridFloat (.flt, .hdr) DEM files from USGS NED (1") in order to implement my own elevation service on my website. I would like to be able to look up an elevation from this fileset, given latitude and longitude as inputs. I use Perl for my website development. The files have a conventional naming scheme, and I am able to get the appropriate tile filename using the lat/lng. Howevever, accessing the internals of the file is where I'm having an issue.
I know the file is in a fairly straightforward format (.flt, apparently called "Gridfloat"), but I could use some help figuring out the magic numbers for calculating where in the file I need to seek to for a given lat/lng, and how to handle byte order and so on so that I end up with an elevation. From what I understand, apparently row ordering can be an issue, as well as byte ordering. I am looking for a recipe that does not involve use of any third party libraries such as GDAL, which I think are overly complicated and slow for what I want to do. I think it should be possible to just open the file, seek to a position based on some calculation, read some bytes and then unpack them into the correct byte order. Here is an example .hdr file that accompanies floatn48w097_1.flt, I think it has the necessary info. There are a bunch of other files that come with the .zip, including .prj, but I believe those are for a commercial program like ArcInfo. I think everything I need should be in the following .hdr file.
ncols 3612
nrows 3612
xllcorner -97.00166666667
yllcorner 46.99833333333
cellsize 0.000277777777778
NODATA_value -9999
byteorder LSBFIRST
What I'm really hoping for is a formula for calculating the row and column from the lat/lng, then another formula for translating the row/column into a position for seek, how many bytes to read, and how to convert those raw bytes into an integer (or whatever it is these files contain). I feel that this could be a very fast operation, without all the overhead involved with the larger libraries which seem to be focused on doing a lot of stuff that I don't need.
I don't need Perl code, just pseudocode showing the calculations for row/col offsets etc would be more than enough. I believe the files are binary format, a straightforward grid of 4-byte numbers. The file example that goes with the .hdr file above has a size of 52186176, and when you multiply the ncols by nrows (from the .hdr), you get 13046544. which divides nicely into the file size by 4. So I assume it's just a matter of getting the right formula for row/col based on lat/lng, and then getting the bytes swizzled into the right order. I've just not done this much.
I found some reference to the Gridfloat format here: coolutils.com/formats/flt so apparently the file consists of a grid of 64-bit floating point values.
Thanks!
Ok, I think I have an answer. The following is Perl routine, which seems to give back reasonable looking elevation values when tested with the USGS NED1 .flt files. The script takes latitude and longitude as command line arguments, looks up the file and indexes into the grid.
#!/usr/bin/perl
use strict;
use POSIX;
use Math::Round;
sub get_elevation
{
my ($lat, $lng) = #_;
my $lat_degree = ceil ($lat);
my $lng_degree = floor ($lng);
my $lat_letter = ($lat >= 0) ? 'n' : 's';
my $lng_letter = ($lng >= 0) ? 'e' : 'w';
my $lng_tilenum = abs($lng_degree);
my $lat_tilenum = abs($lat_degree);
my $tilename = $lat_letter . sprintf('%02d', $lat_tilenum) . $lng_letter . sprintf('%03d',$lng_tilenum);
my $path = "/data/elevation/ned1/$tilename/float${tilename}_1.flt";
print "path = $path\n";
die "No such file" if (!-e($path));
my ($lat_fraction, $lat_integral) = modf (abs($lat));
my $row = floor ((1 - $lat_fraction) * 3600);
my ($lng_fraction, $lng_integral) = modf (abs($lng));
my $col = floor ((1 - $lng_fraction) * 3600);
open(FILE, "<$path");
my $pos = (3612 * 4 * 6) + (3612 * 4 * $row) + (4 * 6) + ($col * 4);
seek (FILE, $pos, SEEK_SET);
my $buffer;
read (FILE, $buffer, 4);
close (FILE);
my ($elevation) = unpack('f', $buffer);
if ($elevation == -9999)
{
return 'undefined';
}
return $elevation;
}
my $lat = $ARGV[0];
my $lng = $ARGV[1];
my $elevation = get_elevation ($lat, $lng);
print "Elevation for ($lat, $lng) = $elevation meters (", $elevation * 3.28084, " feet)\n";
Hope this might be useful to anyone else trying to do the same kind of thing... I've tested this method now and it seems to produce good looking elevation profiles which are smoother than those from the 3" SRTM data.
Neil put me on the right track but I think there's a few problems with his original answer. I've added some fixes and improvements including on-the-fly download of the needed tile from the 1/3 arc second (10 meter) dataset, proper parsing of the header file, and what I believe is corrected indexing.
This is still mostly illustrative and should be improved before production use, particularly, hanging on to the header information and the file handle for repeated queries.
https://gist.github.com/biomiker/32fe34e1fa1bb49ae1135ab6652f596d

sprintf/printf right pad float with zeros in fixed width field

I am using PERL (for legacy reasons) and I would like to format fixed width columns in a CSV file. How do I format the following values:
1.0001
10.0001
100.0001
1000.0001
1000000.1
100000001
into fixed width of 8 by right padding floats with zeros or truncating, BUT if a large integer is encountered the field width must grow to accomodate:
1.000100
10.00010
100.0001
1000.000
1000000.
100000001
I am not performing any operations, so they could possibly be treated as strings or other. I've tried about every combination in the sprintf documentation.
Thanks.
[The question was changed after this was posted. This no longer answers the question.]
substr(sprintf("%.6f", $x), 0, 8)
or
substr($x.("0"x5), 0, 8)
There's probably a neater way, but this example should work:
my #array = qw(1.0001 10.0001 100.0001 1000.0001);
for my $nums (#array) {
$nums .= '0' while length $nums < 8;
print "$nums\n";
}
1.000100
10.00010
100.0001
1000.0001

How can I generate all subsets of a list in Perl?

I have a mathematical set in a Perl array: (1, 2, 3). I'd like to find all the subsets of that set: (1), (2), (3), (1,2), (1,3), (2,3).
With 3 elements this isn't too difficult but if set has 10 elements this gets tricky.
Thoughts?
You can use Data::PowerSet like Matthew mentioned. However, if, as indicated in your example, you only want proper subsets and not every subset, you need to do a little bit more work.
# result: all subsets, except {68, 22, 43}.
my $values = Data::PowerSet->new({max => 2}, 68, 22, 43);
Likewise, if you want to omit the null set, just add the min parameter:
# result: all subsets, except {} and {68, 22, 43}.
my $values = Data::PowerSet->new({min => 1, max => 2}, 68, 22, 43);
Otherwise, to get all subsets, just omit both parameters:
# result: every subset.
my $values = Data::PowerSet->new(68, 22, 43);
See Data::PowerSet, http://coding.derkeiler.com/Archive/Perl/comp.lang.perl/2004-01/0076.html , etc.
Since you say "mathematical set", I assume you mean there are no duplicates.
A naive implementation that works for up to 32 elements:
my $set = [1,2,3];
my #subsets;
for my $count ( 1..(1<<#$set)-2 ) {
push #subsets, [ map $count & (1<<$_) ? $set->[$_] : (), 0..$#$set ];
}
(For the full range of subsets, loop from 0 to (1<<#$set)-1; excluding 0 excludes the null set, excluding (1<<#$set)-1 excludes the original set.)
Update: I'm not advocating this over using a module, just suggesting it in case you are looking to understand how to go about such a problem. In general, each element is either included or excluded from any given subset. You want to pick an element and generate first all possible subsets of the other elements not including your picked element and then all possible subsets of the other elements including your picked element. Recursively apply this to the "generate all possible subsets". Finally, discard the null subset and the non-proper subset. In the above code, each element is assigned a bit. First all subsets
are generated with the high bit on, then all those with it off. For each of those alternatives, subsets are generated first with the next-to-highest bit off, then on. Continuing this until you are just working on the lowest bit, what you end up with is all the possible numbers, in order.
If you don't want to use an existing module or can't then you can simply code your own subset generation algorithm using a bit-mask and a binary counter. Sample code follows -
#!/usr/bin/perl
use strict;
use warnings;
my #set = (1, 2, 3);
my #bitMask = (0, 0, 0); #Same size as #set, initially filled with zeroes
printSubset(\#bitMask, \#set) while ( genMask(\#bitMask, \#set) );
sub printSubset {
my ($bitMask, $set) = #_;
for (0 .. #$bitMask-1) {
print "$set->[$_]" if $bitMask->[$_] == 1;
}
print"\n";
}
sub genMask {
my ($bitMask, $set) = #_;
my $i;
for ($i = 0; $i < #$set && $bitMask->[$i]; $i++) {
$bitMask->[$i] = 0;
}
if ($i < #$set) {
$bitMask->[$i] = 1;
return 1;
}
return 0;
}
Note: I haven't been able to test the code, some bugs might need to be ironed out.
Use Algorithm::ChooseSubsets.
It's a counting problem - for N elements there are exactly 2^N subsets and you have to count from 0 to 2^N - 1 in binary to list them all.
For eg 3 items there are 8 possible subsets: 000, 001, 010, 011, 100, 101, 110 and 111 - the numbers show which members are present.