NOAA-PMEL / LAS

Live Access Server
https://ferret.pmel.noaa.gov/LAS/
The Unlicense
13 stars 5 forks source link

Need better PS, PDF and SVG output from Ferret #1540

Open karlmsmith opened 6 years ago

karlmsmith commented 6 years ago

Reported by @noaaroland on 13 Aug 2013 16:48 UTC I hacked up the LAS_results.jnl file to create a Py_LAS_results.jnl file. Right now the installation copies over the Py_LAS_results.jnl file, but a better approach might be to figure how to skip output types Ferret cannot produce.

And more importantly, the scripts needs some enhancements to write a version of what goes into the annotations.xml into a space at the top of the plot for the PS, PDF and SVG output types. The goal is a single PS, PDF or SVG file with both the annotation and plot together and it seems having the results script do the job is the best approach. Suggestions welcome.

Migrated-From: http://dunkel.pmel.noaa.gov/trac/las/ticket/1533

karlmsmith commented 6 years ago

Comment by @AnsleyManke on 14 Aug 2013 22:07 UTC I guess you're right that to return an annotated PDF we need the annotations in the PDF image, and likewise for the other image formats. I wonder if we can think of a way to do this other than to have Ferret write the text. When we separated out the annotations that was a nice improvement - creating the block of text as html.

karlmsmith commented 6 years ago

Comment by @noaaroland on 15 Aug 2013 14:20 UTC I was thinking that we would try to duplicate the "look and feel" of the "print" page in the PDF, PS and SVG files. In other words not try to recapture the old way of making annotations with the variable name centered below in a larger font with other information various places around the plot frame.

Just do the simplest thing possible which is the current annotations set up of one annotation per line, left-justified with the expectation that long lines would wrap according to some PS/PDF/SVG rules. I know it's hard to scale and position text in a raster image, but perhaps there is some clever way to can just draw line of text, line of text, line of text, image to get this output.

karlmsmith commented 6 years ago

Comment by @noaaroland on 15 Aug 2013 19:39 UTC I don't really think making a separate "image" is a good solution in that text in PS and PDF should be easy and should be scaleable. I added Karl to get his thoughts.

karlmsmith commented 6 years ago

Comment by @AnsleyManke on 15 Aug 2013 21:48 UTC The idea is that the annotations should be part of the image file.

Our html rendering of the annotations has the advantage that a really long dataset url just wraps around. If the script has added seven different "notes" about decimating vectors or plotting on a curvilinear grid or anything else, those just get listed, one after the next.

To make a box of text that's part of the image using Ferret, we'd make a wide margin or define a second viewport. The text viewport would need to be made adjustable, or sizes of text adjusted, to make sure things will fit. If it's a tall skinny image, what's the layout like? We'll have to keep thinking it through.

A different parallel to the current LAS output is to think of the page created by the Print button. It's got the annotations in a table and then the gif image. If somebody saves the gif image to do something with it, it's their responsibility to keep track of what is in the annotations. What if the result of hitting the pdf button were a web page with the annotations and a link to the pdf image?

The other thing to explore is whether there are tools that would let us add the info to the image in some way before returning the result to the end user.

karlmsmith commented 6 years ago

Comment by @karlmsmith on 16 Aug 2013 17:00 UTC Seems like there should be a way to add the annotation lines at the start of the PDF and then copy or encapsulate the normal PDF image. Similarly with other formats.

Using Cairo, I can envision a separate little program that would: (1) create the surface (PNG, PDF, etc) with additional height, (2) render the annotation using Cairo's simple text rendering at this point, -- could easily add the rectangle outline -- can using Pango to perform more elegant text rendering if required (3) read in the desired image -- wouldn't have to be same format, but probably better if it is -- probably best if not raster unless going to PNG with same resolution (4) add the read-in image to the bottom part of the surface, (5) output the whole thing in the desired format.

I wonder if there isn't some existing freeware that could do this for us already. Something like a light-weight inkscape what could be scripted.

Then again, the requirements are so minimal that a light-weight program should be able to be created without much difficulty.

karlmsmith commented 6 years ago

Comment by @noaaroland on 16 Aug 2013 20:31 UTC At the outset of looking at this problem I did some google searching along the lines of HTML to PS and such. There seem to be some creaky Gnu tools, but none of them seemed to address the PDF and SVG issue.

I was hoping something along the lines of what's outlined above might be possible.

Can we just whip up a Python-based Ferret external function that we could call from within the Ferret LAS_results.jnl script to produce these three outputs with text on top when we need them?

I don't even care if the text has a box around it, frankly.

karlmsmith commented 6 years ago

Comment by @karlmsmith on 16 Aug 2013 21:53 UTC I was going to suggest an /HEADERS= option (or whatever name seems appropriate) to the FRAME command, but then realized what I was thinking about, just using Cairo's simple text rendering, would be about the same as what Ansley mentioned doing in her comment above. I had overlooked the wrapping of text issue.

But this is still a reasonable option. This sort of flexible text rendering is what Pango adds to Cairo (eg, pango_layout_set_width, pango_layout_set_wrap - I presume it can be told to break on whatever we want). Pango is standard part of Linux; it is what Linux uses for text rendering, so no new package for users to fetch. And doing something like this from the Qt viewers should be very easy, so this option could become a standard enhancement to PyFerret.

Not sure if doing something in Python (for Cairo images) would give much benefit. I think I would just be using the Python wrappers for Pango to produce the annotations. And I think this would require users to fetch another package.

karlmsmith commented 6 years ago

Comment by @noaaroland on 16 Aug 2013 22:32 UTC I thought of something like frame/title="blah\nfoo" also, but thought it might be too big a violation of the Ferret way of doing things to introduce this concept to PyFerret.

I'm not sure I really understand what's being suggested, but if I get the essence of it then it means that some new command line tool needs get fired up to complete the creation of the PS, PDF and SVG files.

This is certainly possible, but it's expensive. You have to spin up the whole runtime environment again to run the new tool. Python is already running in this case, so I thought we could just whack the problem by running some Python code.

karlmsmith commented 6 years ago

Comment by @karlmsmith on 16 Aug 2013 22:53 UTC No new command-line tool. Just new function calls inside pyferret.

For the -nodisplay case used by LAS, calls to C functions inside a standard shared-object library that is almost certainly already loaded into memory by Linux. Pango is a library of C functions (just like Cairo) and Cairo is designed to play very nicely with Pango. So when the ferret part of pyferret eventually gets around to calling my C function cairoCFerBind_saveWindow in response to the Ferret FRAME command, there would be some added C function calls into the Pango library to format the text to be added to the output. So it should be about as inexpensive as one could hope for.

For displayed cases, which does not apply to LAS, there would just be more PyQt function calls. But again, no separate app.

karlmsmith commented 6 years ago

Comment by @noaaroland on 19 Aug 2013 13:34 UTC Ok, so we have a plan. Let's make it so.

karlmsmith commented 6 years ago

Comment by @karlmsmith on 22 Aug 2013 16:01 UTC I have added FRAME /ANNOTATE= where strarrayvar is a string array variable, with the idea that each string in the array starts on a new line. The strings are passed to the Cairo or Qt graphics engine to render above the normal image (making room in the image for these additional lines.

The question is markup within the lines of text. With Qt I can process full HTML (and add "
" between lines). For Pango (using what they provide) I am restricted to their subset: https://developer.gnome.org/pango/stable/PangoMarkupFormat.html (adding '\n' between lines). But I think this should be sufficient for our purposes (primarily using the convenience tags at the bottom of the page).