PRESTO and large jpg photos

My latest version reads the last 500 records and extracted the larger quakes from the list. I shows the largest first. Quite interesting now with the quakes in Santorini. Most of the time the site records loads of very small quakes in CA, USA

Here is the code:

# Test WIFI network DEMO on Pimoroni PRESTO - Vers 2 with Touch Halt
# Uses data from https://earthquake.usgs.gov
#   ==== Tony Goodhew === 8th Feb 2025 ====
# Shows how to download data from a website, process it to
# extract what you need and display results
# on the 480x480 pixel screen with world map
# Video at https://youtu.be/MOoyETQSido

# Touching the screen halts the program

number = 500  # CHANGE number of records downloaded HERE  <++++++++++++++++++++++
size = 4.5    # Minimum magnetude displaye
max = -999.9  # Rogue value for to find max mag quake

import time
from random import randint
from presto import Presto
import network
import rp2
import requests
rp2.country("GB")
from secrets import WIFI_SSID, WIFI_PASSWORD
import jpegdec
import math

# Setup for the Presto display
presto = Presto(full_res=True)
display = presto.display

WIDTH, HEIGHT = display.get_bounds()

touch = presto.touch # Activate touch

# Create a new JPEG decoder for our PicoGraphics
j = jpegdec.JPEG(display)
eq = 212 # Position of equator on the screen

# Create some colours
BLUE = display.create_pen(20,0,255)
WHITE = display.create_pen(255, 255, 255)
RED = display.create_pen(255,0,0)
ORANGE = display.create_pen(245, 165, 4)
GREEN = display.create_pen(0,255,0)
PINK = display.create_pen(250, 125, 180)
CYAN = display.create_pen(0,255,255)
MAGENTA = display.create_pen(255,0,255)
BLACK = display.create_pen(0, 0, 0)
YELLOW = display.create_pen(255, 255, 0)

# A few procedures to be used later
def wait(z): # delay a while
    time.sleep(z)
    
def clean(): # Clear the screen to Black
    display.set_pen(BLACK)
    display.clear()

# Routine to separate and extract data items from a single downloaded line
def splitup(s):
    string = ""
    items = []

    for p in range(len(s)):
        c = s[p]
#        print(type(c))
        if c != chr(124):
            string = string + c
        else:
            items.append(string)
            string = ""
    items.append(string)        

    # Extract date and time from second item
    dt = items[1]
    date = dt[0:10]
    ttime = dt[11:19]
    return(items,date,ttime)

display.set_font("bitmap8") # Change the font
clean()
display.set_pen(RED)
display.text("Large Quake",40,200,460,8)
display.set_pen(BLUE)
display.text("Data from: https://earthquake.usgs.gov",70,400,480,2)
display.text("Tony Goodhew, Leicester UK",120,450,480,2)
presto.update()
time.sleep(1)

for p in range(35):
    display.set_pen(BLACK)
    display.rectangle(0,190,480,100)
    xx = randint(0,16)-8
    yy = randint(0,16)-8
    display.set_pen(ORANGE)
    display.text("Large Quake",40+xx,200+yy,460,8)
    presto.update()
    time.sleep(0.07)
clean()
display.set_pen(RED)
display.text("Large Quake",40,200,460,8)
presto.update()
time.sleep(0.6)

clean()
display.set_pen(RED)

# Activate WiFi 
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

wlan.connect(WIFI_SSID, WIFI_PASSWORD)
max_wait = 30
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print("Waiting for Wi-Fi connection...")
    display.set_pen(RED)
    display.text("Waiting for Wi-Fi connection...",10,200,460,5)
    presto.update()
    time.sleep(1)

if wlan.status() != 3:
    raise RuntimeError("Network connection failed")
else:
    print("Connected to Wi-Fi network.")
    print(wlan.ifconfig())

clean()
display.set_pen(GREEN)
display.text("Connected to WiFi",50,200,460,5)
display.set_pen(BLUE)
display.text("   Processing",70,260,460,5)
presto.update()

# ===== Main Loop ====
running = True # Main loop flag
while running:
    clean()
    display.set_pen(YELLOW)
    display.text("   Updating",70,260,460,5)
    presto.update()
    
    # Access EarthQuake website and get first 15 lines
    addr = "https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&limit=" + str(number)
    response = requests.get(addr)

    # Separate into lines
    lines = []
    for x in response.content.splitlines():
        xs = str(x)
#        print(str(xs))
        lines.append(str(x))
    response.close()

    
    display.set_pen(YELLOW)
    events = []
#    large = []
    for i in range(1,number + 1):    
        k = splitup(lines[i]) # This does the major lifting using the proc above
        events.append(k)
       
    ''' 
    # List of items for information
    names = ['EventID', 'Time', 'Latitude', 'Longitude', 'Depth/km', 'Author', 'Catalog', 'Contributor',
             'ContributorID', 'MagType', 'Magnitude', 'MagAuthor', 'EventLocationName', 'Date', 'Time']
    '''
    # extract the large ones
    large = []
    for i in range(number):
        k,date,ttime = events[i] # Fetch decoded quake data line
        q = float(k[10])
        if q > size:
            large.append(i)
            if q > max:
                max = q
                ii = i
    print(large)
    print(ii)

    # Show recent event high-lights
    pointers = []
    pointers.append(ii)
    
    for i in large:
        pointers.append(i)
    for i in pointers:
        clean()
        
        j.open_file("Phys480g.jpg")  # World map
        # Decode the JPEG
        j.decode(0, 0, jpegdec.JPEG_SCALE_FULL, dither=True)
            
        k,date,ttime = events[i] # Fetch decoded quake data line
        display.set_pen(BLUE)
        if i == pointers[0]:
            display.set_pen(RED)
        display.text("#"+str(i),0,440,100,3)    # sequence number
        display.text(date + "  --  " + ttime,80,440,460,3)  # Date and time
        
        lat = round(float(k[2]),1)
        long = round(float(k[3]),1)
        if long >177: long = 177 # Fudge for mape IDL edge
        xoff = long * 243/180
        display.set_pen(YELLOW)

        display.line(int(xoff + 240),0, int(xoff + 240),308) # Longitude line
        r = -170  # scale factor - depends on map picture
        noff = r * math.log(math.tan((math.pi/4) + math.radians(lat/4)))
        yy = int(212+noff)
        display.line(0,yy,479,yy)  # Latitude line
        place = k[12]
        place = place[:-1]  # remove final quote character
        display.text(place,0,325,460,2)
        
        display.text("Lat/Long: "+str(lat) + "  "+ str(long),150,350,460,2)
        display.text("Magnitude: " + k[10],0,350,460,2)
        mag = abs(float(k[10])) # Once found a negative mag!!!
        magr = round(math.sqrt(mag * 40.0))
        display.set_pen(GREEN)
        if mag > 2.0:
            display.set_pen(YELLOW)
            if mag > 4.0:
                display.set_pen(ORANGE)
                if mag > 6.0:
                    display.set_pen(RED)
                        
        display.circle(400,400,magr) # Area depends on magnitude
        display.set_pen(YELLOW)
        display.text("Type: " + k[9],0,380,460,2)
        deep = round(float(k[4]),3)
        display.text("Depth/km: "+ str(deep),150,380,460,2)
        
        presto.update()

        # Time delay loop - Cannot use time.sleep()
        # Touching the screen halts the program
        deadline = time.ticks_ms() + 3000
        while time.ticks_ms() < deadline:
            touch.poll()
            if touch.state:
                clean()
                presto.update()
                running = False # Reset flag to finish main loop
                i = 10
                break  # Out of while loop
        if running == False:
            break  # Out of counted 'i' loop

print("\nTerminated by screen touch")

You will need my map

It has a slight flaw near the International Date Line, west of NZ where a small vertical slice of Russia is missing. I’ve inserted a fudge while I look for a better map. I’m pretty pleased with the method and how fast the whole thing runs. The Latitude formula is pretty straight forward in line 210. If you use a different map you need to know the line on the screen for your equator and then adjust r until it hits a city’s Lat. correctly. I used London.

I hope you can get it to work.

1 Like