tomitan100 / org.openhab.binding.bom

OH2 binding for Australian weather forecast and images from Bureau of Meteorology (BOM)
4 stars 3 forks source link

Feature request: Radar images #2

Closed justinj0001 closed 5 years ago

justinj0001 commented 5 years ago

It would be great to be able to have a radar image sequence generated by the binding similar to what's available on the website. Radar images available: ftp://ftp.bom.gov.au/anon/gen/radar/ Transparent overlays (Town names, roads, rivers, topography etc.) available: ftp://ftp.bom.gov.au/anon/gen/radar_transparencies/

tomitan100 commented 5 years ago

Hi Justin,

I'll investigate how I can integrate them.

Regards, Tom

tomitan100 commented 5 years ago

Hi Justin,

The first cut of your request is now available. Please read the updated documentation. Let me know if you have any issue.

Regards, Tom

justinj0001 commented 5 years ago

Hi Tom,

I read through the documentation while I'm away from home this week and it looks great. Can't wait to try it when I get home. Can the image post-processing overlay text? By the command line structure I'm guessing it's using some form of ImageMagick? The only thing I could think of I'd need to add would be the local time of each image instead of UTC as it's only UTC available in the transparencies.
I also noticed in the changelog that you fixed up the daily min/max which was another issue I was going to raise.

tomitan100 commented 5 years ago

I sure can add text/timestamp overlay.

The other overlay you might be interested in is your location marker. That will be achievable once I code the bit that allows you to overlay images from any source.

On Sun, 14 Apr. 2019, 8:56 am justinj0305, notifications@github.com wrote:

Hi Tom,

I read through the documentation while I'm away from home this week and it looks great. Can't wait to try it when I get home. Can the image post-processing overlay text? The only thing I could think of I'd need to add would be the local time of each image instead of UTC as it's only UTC available in the transparencies. I also noticed in the changelog that you fixed up the daily min/max which was another issue I was going to raise.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tomitan100/org.openhab.binding.bom/issues/2#issuecomment-482908466, or mute the thread https://github.com/notifications/unsubscribe-auth/AtMB4N50Qrb1K9NezIruVcb5wEpDAq1Yks5vgny1gaJpZM4cXLz4 .

tomitan100 commented 5 years ago

I have released a new version with local timestamp and ability to overlay images from any sources, including local drive. The idea of the latter is so that you can add your location marker in the form of an image.

I will update the documentation when I get the chance.

justinj0001 commented 5 years ago

Radar works great but when I toggle the text overlay I get an exception thrown. I haven't tried a static overlay yet. 2019-04-17 09:33:47.192 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: java.lang.NullPointerException: null at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264) ~[?:?] at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219) ~[?:?] at sun.awt.FontConfiguration.init(FontConfiguration.java:107) ~[?:?] at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774) ~[?:?] at sun.font.SunFontManager$2.run(SunFontManager.java:431) ~[?:?] at java.security.AccessController.doPrivileged(Native Method) ~[?:?] at sun.font.SunFontManager.<init>(SunFontManager.java:376) ~[?:?] at sun.awt.FcFontManager.<init>(FcFontManager.java:35) ~[?:?] at sun.awt.X11FontManager.<init>(X11FontManager.java:57) ~[?:?] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?] at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:?] at java.lang.Class.newInstance(Class.java:442) ~[?:?] at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83) ~[?:?] at java.security.AccessController.doPrivileged(Native Method) ~[?:?] at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[?:?] at java.awt.Font.getFont2D(Font.java:491) ~[?:?] at java.awt.Font.access$000(Font.java:224) ~[?:?] at java.awt.Font$FontAccessImpl.getFont2D(Font.java:228) ~[?:?] at sun.font.FontUtilities.getFont2D(FontUtilities.java:180) ~[?:?] at sun.java2d.SunGraphics2D.checkFontInfo(SunGraphics2D.java:669) ~[?:?] at sun.java2d.SunGraphics2D.getFontInfo(SunGraphics2D.java:830) ~[?:?] at sun.java2d.pipe.GlyphListPipe.drawString(GlyphListPipe.java:50) ~[?:?] at sun.java2d.pipe.ValidatePipe.drawString(ValidatePipe.java:165) ~[?:?] at sun.java2d.SunGraphics2D.drawString(SunGraphics2D.java:2928) ~[?:?] at org.openhab.binding.bom.internal.image.generator.TextGenerator.generate(TextGenerator.java:55) ~[?:?] at org.openhab.binding.bom.internal.BomImageHandler.embedLocalTimestamp(BomImageHandler.java:347) ~[?:?] at org.openhab.binding.bom.internal.BomImageHandler.generateImages(BomImageHandler.java:296) ~[?:?] at org.openhab.binding.bom.internal.BomImageHandler.refreshImage(BomImageHandler.java:186) ~[?:?] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?] at java.lang.Thread.run(Thread.java:748) [?:?]

tomitan100 commented 5 years ago

Seems like you don't have the font installed. Did you leave it as "Arial" or did you choose your own font? What is your hardware/OS?

Btw, I have updated the documentation.

justinj0001 commented 5 years ago

I did not even think of checking that. I'm running it on Raspbian and it turns out it had no fonts installed. I've added fonts and updated the font name in the timestamp string and it works fine now!

tomitan100 commented 5 years ago

Great!

Btw, I have updated the binding to fix defects and added additional features to support satellite images. My aim to support as many kind of BOM images as possible. Documentation with examples will follow.

justinj0001 commented 5 years ago

How do I properly use the position in a frame config? I would have assumed after cropping that using position would move the cropped frame down but it always seems to apply the position before cropping so I can never have a gap at the top of the frame (I was trying to crop out the 16 pixel banner at the top as it looks ugly in my lovely panel lol).

The following was done in the locations layer so I could see the effect (It wasn't raining here so it was hard to see if things had moved in the series layer). The following examples net the same result yet by looking at it I'd expect that the first example should cut the top 50 pixels off, then move the cropped frame down so that it looks like the image is in the same place with the top cut off. On the other hand the bottom example I'd expect to see the frame in the same place with the bottom cut off. Both seem to do the latter: image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}; image=${pid}.locations.png, crop=0 50 512 462, position=0 50; image=${pid}.range.png

image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}; image=${pid}.locations.png, crop=0 0 512 462; image=${pid}.range.png

tomitan100 commented 5 years ago

Hi Justin,

The banner is actually embedded in the sequence images. So you'll need to apply the crop to the ${series} layer as well. There is no need for position operation.

Anyway having said all that, to achieve what you want all you need is the crop operation in the "Image post processing" field 😊. You don't need to modify individual layers.

Let me know if it doesn't work. I tested that only a couple of times prior to major changes.

p.s You've got to show me your lovely panel.

Regards, Tom

On Thu, 18 Apr. 2019, 7:37 am justinj0305, notifications@github.com wrote:

How do I properly use the position in a frame config? I would have assumed after cropping that using position would move the cropped frame down but it always seems to apply the position before cropping so I can never have a gap at the top of the frame (I was trying to crop out the 16 pixel banner at the top as it looks ugly in my lovely panel lol).

The following was done in the locations layer so I could see the effect (It wasn't raining here so it was hard to see if things had moved in the series layer). The following examples net the same result yet by looking at it I'd expect that the first example should cut the top 50 pixels off, then move the cropped frame down so that it looks like the image is in the same place with the top cut off. On the other hand the bottom example I'd expect to see the frame in the same place with the bottom cut off. Both seem to do the latter: image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}; image=${pid}.locations.png, crop=0 50 512 462, position=0 50; image=${pid}.range.png

image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}; image=${pid}.locations.png, crop=0 0 512 462; image=${pid}.range.png

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tomitan100/org.openhab.binding.bom/issues/2#issuecomment-484300509, or mute the thread https://github.com/notifications/unsubscribe-auth/ALJQDYFGYD2T7BWVW7CL4NDPQ6YDZANCNFSM4HC4XT4A .

justinj0001 commented 5 years ago

I know I need to apply it to the {series} layer (I was applying it to the locations layer to be able to see the results easier) and I can get it cutting off the UTC fine (It's where I stuck the generated time tag), but when I start the crop at 0 16 to take off the top, the image shifts up which means the radar isn't showing in the correct area any more. Here's an example: On the left is the original without cropping, the middle is 50 pixels from the top (crop=0 50 512 462) and you can see it shifts everything up when you crop from the top which is bad when the layers are meant to align, the right is adding position to the 50 pixel crop which I thought would push it down the 50 pixels it just cut off to make them align again (crop=0 50 512 462, position=0 50) but it ends up cropping from the bottom instead. I've applied it to the locations layer again because as you can see there's not much rain around to be able to compare movement change. When I get it right I'll move the image manipulations to the correct layer. Untitled

tomitan100 commented 5 years ago

Hi Justin,

Here is how I achieved it.

To crop out the UTC time use the following in image layers config:

image=IDR.legend.0.png, crop=0 20 512 537; image=${pid}.background.png, crop=0 0 512 492; image=${pid}.topography.png, crop=0 0 512 492; image=${series}, crop=0 0 512 492; image=${pid}.locations.png, crop=0 0 512 492; image=${pid}.range.png, crop=0 0 512 492, opacity=0.6; image=file:///home/tom/bom/location_24.png, position=250 214

(don't forget to remove the custom location marker if you copy above)

I have cropped out 20 pixels of the bottom to remove the UTC time for all layers except the legend image. So basically from y=0 the height will need to 512-20=492. The legend height is 557 pixels, not 512 pixels unlike the rest. To align the legend to match the other cropped layers, 20 pixels need to be removed from the top and the height from the new y will need to be 557-20=537.

This is what you have achieved so far, I think. I'm just writing it out for others.

To get rid of the banner use the following in "Image post-processing" field:

crop=0 16 512 521

Same logic is used here y=16 and height from y=16 to the bottom is 537-16=521.

My timestamp properties:

format=dd/MM/yyyy HH:mm:ss z, font-face=Arial, font-size=16, font-color=#000000, font-weight=bold, position=250 485

See how you go :)

IDR701 0

justinj0001 commented 5 years ago

I got the timestamp cropped no problem, you only need to apply it to the {series} layer as it's the only one that has the timestamp on it. The radar images are 512x512 so I used the following: image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}, crop=0 0 512 498; image=${pid}.locations.png; image=${pid}.range.png

This works and everything aligns correctly as I'm only cropping from the bottom, it was getting complicated when I was trying to crop the grey copyright banner from the top because it wouldn't allow me to reposition the layer after it was cropped which caused it to be misaligned. Again only the {series} set has this banner and needs to be cropped. I was hesitant to crop the entire image at the top as it means it will no longer be square which means it doesn't fit as nicely in a panel widget (I've excluded the legend frame also to keep it square)

tomitan100 commented 5 years ago

Ok sorry now I got what you are trying to do. So basically crop the timestamp and crop the header bits and then re-position so things aligns. I'll see if I can do this.

justinj0001 commented 5 years ago

Yep. So I got the image cropped how I'd like it, but then it doesn't align and position= isn't working like I would have expected it to so I could offset it back to it's original location. I tried the position= in different orders but it always seems to apply first which means it doesn't crop as expected (as per example above)

tomitan100 commented 5 years ago

OK I have fixed it. The problem is you couldn't chain more than one crop instruction per layer. Please reinstall the binding to get the latest version.

This is my image layer properties:

image=IDR.legend.0.png; image=${pid}.background.png; image=${pid}.topography.png; image=${series}, crop=0 0 512 498, crop=0 16 512 482, position=0 16; image=${pid}.locations.png; image=${pid}.range.png;

Thanks for finding the bug!

Screenshot below shows before and after:

pre-post-crop

tomitan100 commented 5 years ago

To explain why position instruction seems to execute first, it was because I was using a hash table, which does not keep the order of instructions as entered. That's also fixed.

justinj0001 commented 5 years ago

Perfect! I just tried it then and it's working exactly as I'd expect. You also don't need to stack 2 crops in this case as you can specify the start and end of the crop box (But the crop wasn't working as expected before either which is fixed now). In this case crop=0 16 512 482 trims both the bottom and the top in one pass, then with position working correctly now it can be realigned. This is what I am using now: image=${pid}.background.png; image=${pid}.topography.png; image=${series}, crop=0 16 512 482, position=0 16; image=${pid}.locations.png; image=${pid}.range.png

I did notice in the update there's the addition of the regex and date range. With the date range field does it search on the server for them (When I checked the server there only seemed to be around 90 mins of images available) or is it caching the images to build the desired image? The update in the documentation didn't go into much detail on the new fields so I was wondering their use case.

tomitan100 commented 5 years ago

Good point about not having to stack crops... I was not thinking :)

The date range is a filter. It does no caching from the starting time. I noticed some products, like the satellite images, have a large number of files. If these files were to be combined the generated GIF would be over 50MB. This is why I added the date range filter with a default of last 24 hours. You can still produce the complete set if you would like by overriding the default.

As for regex field, some products if retrieved without regex will also retrieve unrelated files.

I have provided some examples in the manual where these fields are used and a short reason.