Search code examples
javascriptphpgoogle-mapsflickr

How to link Google Map API markers to Flickr API photo search based on location


I am working on a Google map application that will display locations that are loaded from a mySQL database and LatLng coordinates. I then create markers based on distance from a given center. I have info windows that display information about each point. But I want to be able to load images onto these info windows using Flickr’s API.

I constructed a php file, called photos.php that gets all the photos from a position, which I hardcoded, then displays them. However, I want these images to be displayed on the info windows and I cannot figure how to pass the correct latlng of each marker to the Flickr request.

I have been looking for information and doing research but have yet to find something that I am able to understand.

photos.php


  <?php
    $lat = 32.2226;
    $lng = -110.9747;
    $flickr ='https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=d625f32e9ed8da3da9700a47b73d0dab&lat='.$lat.'&lon='.$lng.'&format=json&nojsoncallback=1';

    $data = json_decode(file_get_contents($flickr));

    $photos = $data->photos->photo;
    foreach ($photos as $photo) {
      $url = 'https://farm'.$photo->farm.'.staticflickr.com/'.$photo->server.'/'.$photo->id.'_'.$photo->secret.'.jpg';
      echo '<img src="'.$url.'">';
    }
   ?>

Code from my index.php file that contains my JS code and retrieves the latlng data from my database.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="style.css">
  <title>My Google Map</title>
</head>
<body>

  <div id="map">

  <script>
    var markers;
    var map;
    var circle;
    var radius = 16093.4 * 5; //50 miles
    var center = {lat:32.2226, lng:-110.9747}
    var list;

    function initMap(){
      markers = [];
      var options = {
        zoom:8,
        center: center
      }
      map = new google.maps.Map(document.getElementById('map'), options);

        getMap();
        initCircle();
      }

    function getMap(){
      clearMarkers();

      var ajax = new XMLHttpRequest();
      var method = "GET";
      var url = "locations.php";
      var asynchronous = true;
      ajax.open(method, url, asynchronous);
      ajax.send();
      ajax.onreadystatechange = function(){
        if(this.readyState == 4 && this.status == 200){
          var data = JSON.parse(this.responseText);
          for(var i = 0; i < data.length; i++){
            var tempLat = parseFloat(data[i].latitude);
            var tempLong = parseFloat(data[i].longitude);
            var latLng = {lat:tempLat, lng:tempLong};
              addMarker({coords:{lat:tempLat, lng:tempLong},
                type:data[i].cache_type,
                difficulty:data[i].difficulty_rating});
                console.log(latLng);
            }
          }
        }
    }

    //Add Marker function
    function addMarker(props){
      list = document.getElementById("locationsPane").getElementsByTagName("ul")[0];
      var marker = new google.maps.Marker({
        position: props.coords,
        map:map,
      });

      var infoWindow = new google.maps.InfoWindow({
        content:"Cache Type: " + props.type + "<br>"
        + "Difficulty: " + props.difficulty
      });

      marker.addListener('click', function(){
        infoWindow.open(map, marker);
      })

      UpdateMarkers(marker);
      markers.push(marker);
      addList(list, marker, props.type, props.difficulty);
    }

    //Initiate info window by clicking side bar item
    function myclick(num){
      google.maps.event.trigger(markers[num], "click");
    }

    function addList(list, marker, type, difficulty){

      if(IsInside(marker.getPosition(), circle.getCenter(), circle.getRadius())){
        var li = document.createElement("li");
        list.appendChild(li);
        li.innerHTML =
        '<a href="javascript:myclick(' + (markers.length-1) + ')">'
        + "<b>Location:</b> "+ marker.getPosition().lat().toFixed(5)
        + ", " + marker.getPosition().lng().toFixed(5)
        + '<\/a><br>';
      }
    }

    //Make circle
    function initCircle(){
      circle = new google.maps.Circle({
        center:{lat:32.2226, lng:-110.9747},
        radius: radius,
        strokeColor: "#0000ff",
        strokeOpacity: 0.6,
        strokeWeight: 2,
        fillColor: "#0000ff",
        fillOpacity: 0.2
      });
      circle.setMap(map);
    }
    function setMapOnAll(map) {
      for (var i = 0; i < markers.length; i++) {
        markers[i].setMap(map);
      }
    }
    function clearMarkers() {
      setMapOnAll(null);
    }

    function clearList(){
      list.innerHTML = '';
    }
    //Get selected index from distance drop-down
    function getSelectedRad(){
      radius = parseFloat(document.getElementById("radius").value);
      circle.setRadius(getMeters(radius));
      clearList();
      getMap();
    }

    function getSelectedType(){
      var ctype = document.getElementById("cachetype").value;
    }

    function getSelectedDifficulty(){
      var difficultyLvl = document.getElementById("difficultylevel").value;
    }
    //Update map and circle center
    function Update(){
      clearList();
      var lat = parseFloat(document.getElementById("latitude").value);
      var lng = parseFloat(document.getElementById("longitude").value);
      map.setCenter({lat:lat, lng:lng});
      circle.setCenter({lat:lat, lng:lng});
      getMap();
    }

    //Update markers - Ensure that they are within the radius
    function UpdateMarkers(marker){
      if(IsInside(marker.getPosition(), circle.getCenter(), circle.getRadius())){
        marker.setVisible(true);
      }else{
        marker.setVisible(false);
      }
    }

    //Convert miles to meters
    function getMeters(i) {
     return i*1609.344;
   }

   //Check the distance of a marker from the center then compare to the Radius
   //If the distance is less than the radius then the marker is within the bounds
   function IsInside(from, to, rad){
     return google.maps.geometry.spherical.computeDistanceBetween(from, to) <= rad;
   }

  </script>
  </div>

  <div id="locationsPane">
      <ul></ul>
  </div>

  <div id="text"></div>
  <script async defer
   src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBQ2k7f0FjJNw9TAodJnTm93BHchk-M20E&callback=initMap">
  </script>

 </body>

</html>

Small sample of location data locations.php

[{"latitude":"32.40638805","0":"32.40638805","longitude":"-114.7141720","1":"-114.7141720","difficulty_rating":"9","2":"9","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"31.93622796","0":"31.93622796","longitude":"-111.3468008","1":"-111.3468008","difficulty_rating":"9","2":"9","cache_type":"Traditional","3":"Traditional"},{"latitude":"32.79804490","0":"32.79804490","longitude":"-113.1862492","1":"-113.1862492","difficulty_rating":"7","2":"7","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"36.98398611","0":"36.98398611","longitude":"-113.0198957","1":"-113.0198957","difficulty_rating":"8","2":"8","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"31.57237360","0":"31.57237360","longitude":"-109.7067254","1":"-109.7067254","difficulty_rating":"9","2":"9","cache_type":"Mystery\/Puzzle","3":"Mystery\/Puzzle"},{"latitude":"32.40104817","0":"32.40104817","longitude":"-112.3002718","1":"-112.3002718","difficulty_rating":"5","2":"5","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"33.40355909","0":"33.40355909","longitude":"-114.4468231","1":"-114.4468231","difficulty_rating":"1","2":"1","cache_type":"Mystery\/Puzzle","3":"Mystery\/Puzzle"},{"latitude":"33.41258752","0":"33.41258752","longitude":"-113.1261994","1":"-113.1261994","difficulty_rating":"7","2":"7","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"31.48120332","0":"31.48120332","longitude":"-109.6336029","1":"-109.6336029","difficulty_rating":"4","2":"4","cache_type":"Traditional","3":"Traditional"},{"latitude":"36.65950176","0":"36.65950176","longitude":"-110.0774749","1":"-110.0774749","difficulty_rating":"2","2":"2","cache_type":"Mystery\/Puzzle","3":"Mystery\/Puzzle"},{"latitude":"33.16987671","0":"33.16987671","longitude":"-112.1256549","1":"-112.1256549","difficulty_rating":"5","2":"5","cache_type":"Multi-Cache","3":"Multi-Cache"},{"latitude":"35.22192709","0":"35.22192709","longitude":"-110.1382606","1":"-110.1382606","difficulty_rating":"5","2":"5","cache_type":"Traditional","3":"Traditional"}]

Again, all I really want to do at this point is to add the corresponding photos to each marker's info window. Basically, how can I pass the coordinates from the markers to the Flickr photo search?


Solution

  • One option would be to do an AJAX request to the flicker API using jquery when the Marker is clicked, then append the image(s) to the InfoWindow content.

    marker.addListener('click', function(){
      infoWindow.open(map, marker);
      // request data from the flicker API
      $.ajax("https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=d625f32e9ed8da3da9700a47b73d0dab&lat="+this.getPosition().lat()+"&lon="+this.getPosition().lng()+"&format=json&nojsoncallback=1", {
        success: function(data) {
        var photo = data.photos.photo[0];
        var url = 'https://farm'+photo.farm+'.staticflickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'.jpg';
         $('#flickercontent').prepend('<img id="theImg" src="'+url+'" />')
        },
        error: function(jqXHR, textStatus, errorThrown) {
          console.log("error "+textStatus+" "+errorThrown)
        }
      })
    })
    

    proof of concept fiddle

    screenshot of resulting map with InfoWindow open

    code snippet:

    /* Always set the map height explicitly to define the size of the div
     * element that contains the map. */
    
    #map {
      height: 90%;
    }
    
    
    /* Optional: Makes the sample page fill the window. */
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="map"></div>
    <script>
      var markers;
      var map;
      var circle;
      var radius = 16093.4 * 5; //50 miles
      var center = {
        lat: 32.2226,
        lng: -110.9747
      }
      var list;
    
      function initMap() {
        markers = [];
        var options = {
          zoom: 8,
          center: center
        }
        map = new google.maps.Map(document.getElementById('map'), options);
        initCircle();
        getMap();
    
      }
    
      function getMap() {
        clearMarkers();
    
        for (var i = 0; i < data.length; i++) {
          var tempLat = parseFloat(data[i].latitude);
          var tempLong = parseFloat(data[i].longitude);
          var latLng = {
            lat: tempLat,
            lng: tempLong
          };
          addMarker({
            coords: {
              lat: tempLat,
              lng: tempLong
            },
            type: data[i].cache_type,
            difficulty: data[i].difficulty_rating
          });
          console.log(latLng);
        }
      }
    
      //Add Marker function
      function addMarker(props) {
        list = document.getElementById("locationsPane").getElementsByTagName("ul")[0];
        var marker = new google.maps.Marker({
          position: props.coords,
          map: map,
        });
    
        var infoWindow = new google.maps.InfoWindow({
          content: "Cache Type: " + props.type + "<br>" +
            "Difficulty: " + props.difficulty + "<br>" +
            "<div id='flickercontent'></div>"
        });
    
        marker.addListener('click', function() {
          console.log("click " + this.getPosition().toUrlValue(6))
          infoWindow.open(map, marker);
          $.ajax("https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=d625f32e9ed8da3da9700a47b73d0dab&lat=" + this.getPosition().lat() + "&lon=" + this.getPosition().lng() + "&format=json&nojsoncallback=1", {
            success: function(data) {
              // foreach ($photos as $photo) {
              console.log(data);
              var photo = data.photos.photo[0];
              var url = 'https://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '.jpg';
              var img = new Image();
              img.src = url;
              $('#flickercontent').prepend('<img id="theImg" src="' + url + '" />')
              // document.getElementById('flickercontent').appendElement(img);
            },
            error: function(jqXHR, textStatus, errorThrown) {
              console.log("error " + textStatus + " " + errorThrown)
            }
          })
        })
    
        UpdateMarkers(marker);
        markers.push(marker);
        addList(list, marker, props.type, props.difficulty);
      }
    
      //Initiate info window by clicking side bar item
      function myclick(num) {
        google.maps.event.trigger(markers[num], "click");
      }
    
      function addList(list, marker, type, difficulty) {
        // if (!circle || !circle.getCenter) return;
        if (IsInside(marker.getPosition(), circle.getCenter(), circle.getRadius())) {
          var li = document.createElement("li");
          list.appendChild(li);
          li.innerHTML =
            '<a href="javascript:myclick(' + (markers.length - 1) + ')">' +
            "<b>Location:</b> " + marker.getPosition().lat().toFixed(5) +
            ", " + marker.getPosition().lng().toFixed(5) +
            '<\/a><br>';
        }
      }
    
      //Make circle
      function initCircle() {
        circle = new google.maps.Circle({
          center: {
            lat: 32.2226,
            lng: -110.9747
          },
          radius: radius,
          strokeColor: "#0000ff",
          strokeOpacity: 0.6,
          strokeWeight: 2,
          fillColor: "#0000ff",
          fillOpacity: 0.2
        });
        circle.setMap(map);
      }
    
      function setMapOnAll(map) {
        for (var i = 0; i < markers.length; i++) {
          markers[i].setMap(map);
        }
      }
    
      function clearMarkers() {
        setMapOnAll(null);
      }
    
      function clearList() {
        list.innerHTML = '';
      }
      //Get selected index from distance drop-down
      function getSelectedRad() {
        radius = parseFloat(document.getElementById("radius").value);
        circle.setRadius(getMeters(radius));
        clearList();
        getMap();
      }
    
      function getSelectedType() {
        var ctype = document.getElementById("cachetype").value;
      }
    
      function getSelectedDifficulty() {
        var difficultyLvl = document.getElementById("difficultylevel").value;
      }
      //Update map and circle center
      function Update() {
        clearList();
        var lat = parseFloat(document.getElementById("latitude").value);
        var lng = parseFloat(document.getElementById("longitude").value);
        map.setCenter({
          lat: lat,
          lng: lng
        });
        circle.setCenter({
          lat: lat,
          lng: lng
        });
        getMap();
      }
    
      //Update markers - Ensure that they are within the radius
      function UpdateMarkers(marker) {
        // if (!circle || !circle.getCenter) return;
        if (IsInside(marker.getPosition(), circle.getCenter(), circle.getRadius())) {
          marker.setVisible(true);
        } else {
          marker.setVisible(false);
        }
      }
    
      //Convert miles to meters
      function getMeters(i) {
        return i * 1609.344;
      }
    
      //Check the distance of a marker from the center then compare to the Radius
      //If the distance is less than the radius then the marker is within the bounds
      function IsInside(from, to, rad) {
        return google.maps.geometry.spherical.computeDistanceBetween(from, to) <= rad;
      }
    
      var data = [{
        "latitude": "32.40638805",
        "0": "32.40638805",
        "longitude": "-114.7141720",
        "1": "-114.7141720",
        "difficulty_rating": "9",
        "2": "9",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "31.93622796",
        "0": "31.93622796",
        "longitude": "-111.3468008",
        "1": "-111.3468008",
        "difficulty_rating": "9",
        "2": "9",
        "cache_type": "Traditional",
        "3": "Traditional"
      }, {
        "latitude": "32.79804490",
        "0": "32.79804490",
        "longitude": "-113.1862492",
        "1": "-113.1862492",
        "difficulty_rating": "7",
        "2": "7",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "36.98398611",
        "0": "36.98398611",
        "longitude": "-113.0198957",
        "1": "-113.0198957",
        "difficulty_rating": "8",
        "2": "8",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "31.57237360",
        "0": "31.57237360",
        "longitude": "-109.7067254",
        "1": "-109.7067254",
        "difficulty_rating": "9",
        "2": "9",
        "cache_type": "Mystery\/Puzzle",
        "3": "Mystery\/Puzzle"
      }, {
        "latitude": "32.40104817",
        "0": "32.40104817",
        "longitude": "-112.3002718",
        "1": "-112.3002718",
        "difficulty_rating": "5",
        "2": "5",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "33.40355909",
        "0": "33.40355909",
        "longitude": "-114.4468231",
        "1": "-114.4468231",
        "difficulty_rating": "1",
        "2": "1",
        "cache_type": "Mystery\/Puzzle",
        "3": "Mystery\/Puzzle"
      }, {
        "latitude": "33.41258752",
        "0": "33.41258752",
        "longitude": "-113.1261994",
        "1": "-113.1261994",
        "difficulty_rating": "7",
        "2": "7",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "31.48120332",
        "0": "31.48120332",
        "longitude": "-109.6336029",
        "1": "-109.6336029",
        "difficulty_rating": "4",
        "2": "4",
        "cache_type": "Traditional",
        "3": "Traditional"
      }, {
        "latitude": "36.65950176",
        "0": "36.65950176",
        "longitude": "-110.0774749",
        "1": "-110.0774749",
        "difficulty_rating": "2",
        "2": "2",
        "cache_type": "Mystery\/Puzzle",
        "3": "Mystery\/Puzzle"
      }, {
        "latitude": "33.16987671",
        "0": "33.16987671",
        "longitude": "-112.1256549",
        "1": "-112.1256549",
        "difficulty_rating": "5",
        "2": "5",
        "cache_type": "Multi-Cache",
        "3": "Multi-Cache"
      }, {
        "latitude": "35.22192709",
        "0": "35.22192709",
        "longitude": "-110.1382606",
        "1": "-110.1382606",
        "difficulty_rating": "5",
        "2": "5",
        "cache_type": "Traditional",
        "3": "Traditional"
      }];
    </script>
    
    <div id="locationsPane">
      <ul></ul>
    </div>
    
    <div id="text"></div>
    <!-- Replace the value of the key parameter with your own API key. -->
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=geometry"></script>