#!/bin/bash # ============================================ # Make a click map of all our locals. # -------------------------------------------- # Alfred Klomp, May 2006 # ============================================ # Setup: MAP_WIDTH_IN_INCH=3 # Total map width, 1 inch = 300 pixels STAR_WIDTH_IN_INCH=0.05 # Size of the little stars LAT_MARGIN=2 # Top/bottom margin in degrees latitude LON_MARGIN=3 # Left/right margin in degrees longitude # Input: the locations to plot are in a file called # coordinates.txt in the following form: # -------------------------------------------- # LOCALCODE:COUNTRY:NAME:LAT:LONG # LOCALCODE:COUNTRY:NAME:LAT:LONG # [ ... etc ... ] # -------------------------------------------- # First, we have to find out the extents of our map. We parse the coordinate # file to find the min/max lat/long pairs, and round off the values. MIN_LAT=$( cat coordinates.txt | awk 'BEGIN{FS=":"}{print $3}' | sort -n | head -n1 | awk '{ print int($1 - '$LAT_MARGIN') }' ) MAX_LAT=$( cat coordinates.txt | awk 'BEGIN{FS=":"}{print $3}' | sort -nr | head -n1 | awk '{ print int($1 + '$LAT_MARGIN') }' ) MIN_LON=$( cat coordinates.txt | awk 'BEGIN{FS=":"}{print $4}' | sort -n | head -n1 | awk '{ print int($1 - '$LON_MARGIN') }' ) MAX_LON=$( cat coordinates.txt | awk 'BEGIN{FS=":"}{print $4}' | sort -nr | head -n1 | awk '{ print int($1 + '$LON_MARGIN') }') # Create base map. pscoast -K -R$MIN_LON/$MAX_LON/$MIN_LAT/$MAX_LAT -JM${MAP_WIDTH_IN_INCH}i -P -G41/22/111 -S153/204/255 -Dh > clickmap.eps # Export all coordinates from the master file to a temp file containing "LON LAT" pairs. awk 'BEGIN{FS=":"}{ print $4 " " $3 }' coordinates.txt > coordinates.tmp # Plot LON LAT pairs on our base map as stars. psxy -R -J -O -K -Sa${STAR_WIDTH_IN_INCH}i -Gyellow coordinates.tmp >> clickmap.eps # Plot LON LAT pairs again, as points this time, to stdout for further filtering: psxy -R -J -O -Sp coordinates.tmp | \ # Of all the postscript on stdout, we're only interested in the point drawing commands: egrep "[0-9]* [0-9]* [0-9]* O" | \ # We filter out the x and y coordinates and write them to a file for later revisiting: awk '{ print $2, $3 }' > clickmap.coords # Close EPS map file by writing a bogus coordinate: echo "9999 9999" | psxy -J -R -O >> clickmap.eps # Render to PNG with Ghostscript: gs -sDEVICE=png16m -dGraphicsAlphaBits=2 -sOutputFile=clickmap.png -r300 -dSAFER -dBATCH -dNOPAUSE clickmap.eps # Trim white border off image: convert -trim clickmap.png clickmap.out.png mv clickmap.out.png clickmap.png # Now we have to convert our x y coordinate pairs to pixel coordinates. # The postscript origin is bottom left, the pixel origin is top left. # So we have to invert the y coordinates. ( y := HEIGHT - y ) # Get height of PNG image IMAGE_HEIGHT=$( file clickmap.png | egrep -o "x [0-9]*" | awk '{ print $2 }' ) # Invert Y coordinate in file: awk '{ print $1 ":" '${IMAGE_HEIGHT}' - $2 - 1 ":" }' clickmap.coords > clickmap.coords.tmp # Note: the one-to-one correspondence of postscript coordinates to pixels # only works when both the map and the raster image are rendered at 300 dpi, # which is the native resolution for GMT. # If you want a different size map, adjust the WIDTH_IN_INCH parameter at # the beginning of this script, not the rasterization resolution! # Get CLICK_RADIUS, it's half of STAR_WIDTH_IN_INCH * 300 pixels/inch: CLICK_RADIUS=$( echo "scale=0; ${STAR_WIDTH_IN_INCH} * 300 / 2" | bc ) # Rejoin pixel coordinates and original file of locals, # delete tab character inserted in rejoining process: paste clickmap.coords.tmp coordinates.txt | tr -d '\t' | \ # Make HTML code from our pixel coordinate file: awk 'BEGIN { FS=":"; print "" } \ { print " \""" } \ END{ print "" }' > clickmap.html # Clean up rm clickmap.coords rm clickmap.coords.tmp rm coordinates.tmp rm clickmap.eps # Optional: use pngquant to reduce the colour depth pngquant 16 clickmap.png mv clickmap-fs8.png clickmap.png # Output: clickmap.png = the clickmap image # clickmap.html = the HTML for the clickmap