Reputation: 999
I have a map of Israel.
I need to create a function that gets two double parameters (longitude and latitude) and that function should draw a small circle on that area in the map image.
I have the following info about the map:
I need to convert the coordinates I get to pixel X, Y based on that image.
There's the following map image:
For example (Not an accurate example, it is just an example so you understand what I mean), the top-left coordinate is 33.5, 34 and the X, Y of it is 0,0 on the map.
How can I convert these coordinates to X, Y coordinates?
I tried this answer but it didn't really work, it shows me at 31.5, 34.5
instead of at 33, 34
.
UPDATE: here's a dummy quick code example of the other question;
public class MapRenderer extends JFrame {
public static void main(String... args) throws IOException {
new MapRenderer();
}
public MapRenderer() throws IOException {
setSize(new Dimension(614, 1141));
add(new TestPane());
setVisible(true);
}
}
class TestPane extends JPanel {
private BufferedImage image;
public TestPane() throws IOException {
File file = new File("israel_map.jpg");
BufferedImage image = ImageIO.read(file);
this.image = image;
}
@Override
public void paintComponent(Graphics g) {
double lon = 34;
double lat = 33;
int mapW = 614;
int mapH = 1141;
double x = (lon + 180) * (mapW / 360);
double latRad = lat * Math.PI / 180;
double mercN = Math.log( Math.tan( (Math.PI / 4) + (latRad / 2)) );
double y = (mapH / 2) - (mapW * mercN / (2 * Math.PI));
System.out.println("[lon: " + lon + " lat: " + lat + "]: X: " + x + " Y: " + y);
g.drawImage(image, 0, 0, null);
g.setColor(Color.RED);
g.drawOval((int) x, (int) y, 5, 5);
}
}
Output:
[lon: 34.0 lat: 33.0]: X: 214.0 Y: 510.3190109117399
screenshot:
https://gyazo.com/5a19dece37ebace496c6b8d68eb9ec3c
Upvotes: 3
Views: 7626
Reputation: 1246
You need to add offsets and lengths of the map in longitude/latitude in addition to pixels. Then you can just do a conversion.
static final int mapWidth = 614, mapHeight = 1141;
// offsets
static final double mapLongitudeStart = 33.5, mapLatitudeStart = 33.5;
// length of map in long/lat
static final double mapLongitude = 36.5-mapLongitudeStart,
// invert because it decreases as you go down
mapLatitude = mapLatitudeStart-29.5;
private static Point getPositionOnScreen(double longitude, double latitude){
// use offsets
longitude -= mapLongitudeStart;
// do inverse because the latitude increases as we go up but the y decreases as we go up.
// if we didn't do the inverse then all the y values would be negative.
latitude = mapLatitudeStart-latitude;
// set x & y using conversion
int x = (int) (mapWidth*(longitude/mapLongitude));
int y = (int) (mapHeight*(latitude/mapLatitude));
return new Point(x, y);
}
public static void main(String[] args) {
System.out.println(getPositionOnScreen(33.5, 33.5).toString());
System.out.println(getPositionOnScreen(35, 32).toString());
System.out.println(getPositionOnScreen(36.5, 29.5).toString());
}
This will print out the following:
java.awt.Point[x=0,y=0]
java.awt.Point[x=307,y=427]
java.awt.Point[x=614,y=1141]
Upvotes: 2
Reputation: 628
Your code does not take into account that your map is not the entire world map. You need to adjust it so that it has an offset (because the top left of the map is not 0,0 so to speak) and so that it doesn't think the width of the map is 360' and the height 180'.
For starters x = (longitude+180)*(mapWidth/360)
should be more like x = (longitude+<distance west of prime meridian of left side of map>)*(mapWidth/<width of map in degrees>)
Upvotes: 0