1 package tim.prune.gui.map;
4 import java.awt.image.BufferedImage;
7 * Class to manage coordinate conversions and other stuff for maps
9 public abstract class MapUtils
12 * Transform a longitude into an x coordinate
13 * @param inLon longitude in degrees
14 * @return scaled X value from 0 to 1
16 public static double getXFromLongitude(double inLon)
18 return (inLon + 180.0) / 360.0;
22 * Transform a latitude into a y coordinate
23 * @param inLat latitude in degrees
24 * @return scaled Y value from 0 to 1
26 public static double getYFromLatitude(double inLat)
28 return (1 - Math.log(Math.tan(inLat * Math.PI / 180) + 1 / Math.cos(inLat * Math.PI / 180)) / Math.PI) / 2;
32 * Transform an x coordinate into a longitude
33 * @param inX scaled X value from 0(-180deg) to 1(+180deg)
34 * @return longitude in degrees
36 public static double getLongitudeFromX(double inX)
38 // Ensure x is really between 0 and 1 (to wrap longitudes)
39 double x = ((inX % 1.0) + 1.0) % 1.0;
40 // Note: First %1.0 restricts range to (-1,1), then +1.0 shifts to (0,2)
41 // Finally, %1.0 to give (0,1)
42 return x * 360.0 - 180.0;
46 * Transform a y coordinate into a latitude
47 * @param inY scaled Y value from 0 to 1
48 * @return latitude in degrees
50 public static double getLatitudeFromY(double inY)
52 double n = Math.PI * (1 - 2 * inY);
53 return 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
57 * Tests whether there are any dark pixels in the image within the specified x,y rectangle
58 * @param inImage image to test
59 * @param inX left X coordinate
60 * @param inY bottom Y coordinate
61 * @param inWidth width of rectangle
62 * @param inHeight height of rectangle
63 * @param inTextColour colour of text
64 * @return true if the rectangle overlaps stuff too close to the given colour
66 public static boolean overlapsPoints(BufferedImage inImage, int inX, int inY,
67 int inWidth, int inHeight, Color inTextColour)
69 // each of the colour channels must be further away than this to count as empty
70 final int BRIGHTNESS_LIMIT = 80;
71 final int textRGB = inTextColour.getRGB();
72 final int textLow = textRGB & 255;
73 final int textMid = (textRGB >> 8) & 255;
74 final int textHigh = (textRGB >> 16) & 255;
77 // loop over x coordinate of rectangle
78 for (int x=0; x<inWidth; x++)
80 // loop over y coordinate of rectangle
81 for (int y=0; y<inHeight; y++)
83 int pixelColor = inImage.getRGB(inX + x, inY - y);
84 // split into four components rgba
85 int pixLow = pixelColor & 255;
86 int pixMid = (pixelColor >> 8) & 255;
87 int pixHigh = (pixelColor >> 16) & 255;
88 //int fourthBit = (pixelColor >> 24) & 255; // alpha ignored
89 // If colours are too close in any channel then it's an overlap
90 if (Math.abs(pixLow-textLow) < BRIGHTNESS_LIMIT ||
91 Math.abs(pixMid-textMid) < BRIGHTNESS_LIMIT ||
92 Math.abs(pixHigh-textHigh) < BRIGHTNESS_LIMIT) {return true;}
96 catch (NullPointerException e) {
97 // ignore null pointers, just return false