Map latitude and longitude coordinates to a an image?

Hi I’m trying to mark multiple points on a map using their latitude and longitude coordinates. I’ve written a for loop which gets these coordinates as well as population data from the CSV file but I’m unsure how I’d get these values then printed onto the map uses an ellipse to mark them for example. I’ve also been able to load the map itself.

hey cool that you made progress but can you continue on the previous one or at least point to the previous thread?

not that I want to take the credit but it helps people to understand the context :slight_smile:

This video shows how to map lat/lon to a map image. But this case it’s a world map so perhaps you need to rescale it somehow.

Yes that’s why I wrote you have to rescale, but the idea is the same and anyways it’s good to learn something instead of copy and paste answers from the forum :slight_smile: (by the way processing version is available on their github).

And rescaling is not trivial. Do you want to share the map image so we can understand the situation better? You didn’t mention anything about the map, so we have no idea if it’s a map of your neighborhood, city, country or the world :slight_smile: (I’m half joking but half serious - you mentioned a map of the UK but you didn’t add link to that thread. Always give information as much as possible because we are here not to do a detective job but to support you as volunteers. If you don’t provide enough information, most of them will simply ignore the thread)

thanks, but again, give us the full code because I’m pretty sure something is wrong in the other part of the code that is causing the “missing ellipse” issue. If you cannot give the whole code, try to make a scaled down (but fully runnable) version that describes the issue.

remapping to that specific map is not easy! I have a call so I cannot look into it now.

PImage map; 
float zoom = 1;
float posX = 0;
float posY = 0;
float lat = 51.5074;
float lon = -0.1278;

void setup() {
  size (800, 800, P3D);
  loadData();
  map = loadImage("uk-admin.jpg");
 
}

void draw () {
 background (0);
 translate(posX,posY);
 scale(zoom);
 image(map, 0,0, width, height);
 camera(width/2, height/2, (height/2) / tan(PI*30.0 / 180.0),width/2.0, height/2.0 , 0, 0, 1, 0);


Table table;

void loadData() {
  table = loadTable("data.csv", "header");

  for (int i = 0; i < table.getRowCount(); i++) {
    TableRow row = table.getRow(i);

    float lat = row.getFloat("latitude");
    float lon =  row.getFloat("longitude");
    
     lat = map(lat, 90.0, -90.0, 0, height);
     lon = map(lon, -180.0, 180.0, 0, width);
     fill(255);                      
     stroke(10);
     ellipse(lon, lat, 30, 30);
   
   
}}
}

ok there are few problems. First, you have loadData inside draw function. That doesn’t mean the ellipses are drawn in the draw loop. In fact, you call this function in setup, so the csv file is loaded, and then you draw ellipses. This is in setup so it happens only once. Then, draw is called in a loop, which draws the map image, and that’s it, because loadData is just a function declaration and it is not called or activated.

Instead, you should call only this line in setup

table = loadTable("data.csv", "header");

The rest, for loop and ellipse draw, should be directly inside draw (not inside loadData) but after image so the ellipses will be drawn after the map is drawn.

Second, camera is not useful when you work with 2D. If you know what you are doing then it’s ok, but if you are not sure, you should delete that line and use translate and scale to manipulate the position. But you should keep posX and posY to 0, and zoom to 1 until you figure out how to align the ellipses to the map because it will just add more complexity.

And finally, how can we align the ellipses to the map? It’s hard. Basically, what you want is the longitude and latitude of the 4 corners of your map image. If you know them, you can replace the lines of map functions to something like this

     lat = map(lat, latitudeTop, latitudeBottom, 0, height);
     lon = map(lon, longitudeLeft, longitudeRight, 0, width);

and in Dan’s video, it’s simple because they know that latitude goes from 90 to -90, and longitude from -180 to 180. In your case, it’s quite arbitrary. In fact, 3 corners are on the sea and there is no obvious landmark that you can spot.

A “clean” way to solve this problem is to find a few pairs that map pixel coordinate to the actual lon/lat, and use linear regression to find the mapping. This requires some understanding of linear algebra, and while it is not complicated, I think it’s not what you are looking for (unless someone makes it for you).

A rather dirty but doable solution is to find the mapping manually. You can “eye” the longitude and latitude of each corner of the map and use them in the map functions above. Run the program, and the ellipses are perhaps off from where you want them. Then you tweak the values, and run it again. Actually, there is “tweak mode” in Processing (from sketch menu), and this allows you to change (or tweak) values on the fly. This may help you to find the right mapping relatively fast.

2 Likes

I ended up loading it all myself then manually, took some time but its all working fine now anyway. I had to put the loadData(); into the draw function instead of the setup function (which it originally was in) and it allowed for the ellipse to be presented on the map.

Glad that you figured it out! Although you don’t have to, sharing the code would be helpful for others who found this thread with the same question :slight_smile:

By the way, I meant you should split loadData into two parts: one for setup and the other for draw. Specifically, the first line (as I quoted above) should not be in draw because that means you are accessing the file 60 times per second, which is complete waste of resource (as the file won’t change).