Thursday, January 25, 2024

One Hour AI Map Challenge

Welcome to the One Hour AI Map Challenge, in which I attempt to make an interactive 'Meet in the Middle' map in under 60 minutes. The only other rule of this challenge is that all the JavaScript code for the map has to be written by Google's generative artificial intelligence Bard.

TLDR - Here is Bard's Meet in the Middle interactive map after 1 hour's work

Over the years I've seen many examples of maps which will work out the best place for two (or more) people to meet. Whatshalfway.com is a good example of a map tool which allows you to find places to meet halfway between two different locations. 

It isn't fair to expect Bard to create a map as good as whatshalfway in only one hour. In fact in 60 minutes I really only want to create a very simple map. This map should: 

1. Have a click event to add two markers to the map based on where the user clicks. 

2. Calculate the midpoint between those two markers 

3. Add a third marker to the map to show the midway point between these two locations. 

Prompt No.1:

My first prompt for Bard was:

Give me the html, css and javascript for a Leaflet.js map with a width & height of 100%

Unfortunately I immediately ran into a problem with Bard's response. The interactive map created from Bard's suggestions didn't work. In fact all I got was a blank web page. However using Chrome's developer tools quickly revealed the problem. Bard's response included an invalid 'digest in the 'integrity' attribute for resource - https://unpkg.com/leaflet@1.9.3/dist/leaflet.js'. In other words the cryptographic hash in the URL for the Leaflet Javascript file is wrong and the Leaflet JavaScript is failing to load in the browser.

No worries. A quick reference to the Leaflet.js Quick Start Guide allowed me to grab the correct Leaflet JavaScript and CSS files. Swapping in the correct Leaflet Javascript and CSS files and we are in action and we actually have a map. 

Time to add some markers to the map.

Prompt No.2:

Add a javascript click event to add a marker to the map

In response to this prompt Bard suggested the following map click event function:
map.on('click', function(e) {
  var lat = e.latlng.lat;
  var lng = e.latlng.lng;
  var marker = L.marker([lat, lng]).addTo(map);
  // Optional customization
  marker.setIcon(L.icon({ iconUrl: '/my-marker-icon.png' }));
  marker.bindPopup("I'm a new marker!");
});
Bard's function worked perfectly and my map could now add a marker when clicked (although I removed the last two lines for adding a customized marker). Now we need a second marker! 

Prompt No.3:

Create another click event to add a marker (markerB) to the map

In response to this prompt Bard gave me another (very similar) function:
map.on('click', function(e) {
  var lat = e.latlng.lat;
  var lng = e.latlng.lng;
  var markerB = L.marker([lat, lng], {
    icon: L.icon({
      iconUrl: 'marker-B-icon.png',
      iconSize: [32, 37]
    })
  }).addTo(map);
  markerB.bindPopup("I'm marker B!");
});
Now my map adds a second marker when clicked for the second time and calls this marker 'markerB' (again I actually omitted the suggested custom marker code). For the sake of coherence I also went back to the function for the first marker and changed its variable name to 'markerA'.

We now have a map which can be clicked on to add two locations. We have a first marker with the name 'markerA' and a second marker called 'markerB'. All we have to do now is calculate the midway point between these two markers and add a third marker to show this midway point on the map.

Prompt No.4:

Find the midway point between markerA and markerB and add a third marker at this point.

In response to this prompt Bard gave me two functions. The first calculates the midpoint between the two clicked locations:
function calculateMidpoint(markerA, markerB) {
  const latA = markerA.getLatLng().lat;
  const lngA = markerA.getLatLng().lng;
  const latB = markerB.getLatLng().lat;
  const lngB = markerB.getLatLng().lng;

  const midLat = (latA + latB) / 2;
  const midLng = (lngA + lngB) / 2;

  return [midLat, midLng];
}
 
and a second function to add a marker at the midpoint:
function measureDistance(markerA, markerB) {
  const midpoint = calculateMidpoint(markerA, markerB);
  const markerC = L.marker(midpoint).addTo(map);
  markerC.bindPopup("Midpoint between A and B");
}
Houston we have a problem! Unfortunately when we now load our map no midpoint marker is added to the map. We can also keep on adding infinite markers to the map. So we need to create a function to remove click events from the map after two markers have been added.

Time for another prompt!

Prompt No.5:

Check if two markers have been added to the map and remove the click events from the map. Add the midpoint marker to the map after markerB is added to the map.

In response to this prompt Bard wrapped the click events inside a counter and removed click events once the counter reached 2.

Finished (for now)

45 minutes after starting work we now have a workable but very, very basic Meet in the Middle map. This map is not going to win any prizes for usability or functionality. However I still think Bard is an impressive aid for programmers. Personally it has replaced Stack Overflow as my default destination for when I get stuck on a problem and find myself banging my head against a brick wall. 

Who knows how our Meet in the Middle Map might be developed if we employ Bard for a second hour? To be continued ...

3 comments:

mpegg said...

This is great Keir! Looking forward to what hour #2 brings. Maybe a local search around the midpoint to look for a coffee or lunch spot? :)

Keir Clarke said...

Thanks Mike. Great minds think alike. Check out today's post (Jan 28)!

mpegg said...

Memories of the mezzoman meet in the middle tool from way back!