How to add different labels in respect of different locations query result with Google Maps JavaScript Api?

Viewed 297

I have a code in maps JS api. I have 2 query search , one for finding near pharmacy, and other for hospitals. I want to label the returning markers with F for pharmacy and H for hospitals. How do I make this separation? And how can I put in query to search for hospitals and pharmacies? I tried many combinations but it return only hospital or pharmacies.

<script
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD6uiXpiTDkhGcAG9X4G8vm1rF2eXQzXMI&callback=initialize&libraries=places&v=weekly"
        defer></script>

let map;
        let service;
        let infowindow;
        function initialize() {
            infowindow = new google.maps.InfoWindow();
            //Map options
            var options = {
                center: userPosition,
                zoom: 14,
                // disableDefaultUI: true,
            }
            //New map
            map = new
                google.maps.Map(document.getElementById("map"), options);

            var request = {
                location: userPosition,
                radius: '2000',
                query: "hospital, pharmacy",
                // query: 'spital',
            };

            service = new google.maps.places.PlacesService(map);
            service.textSearch(request, callback);;

            function addUserLocationMarker() {
                marker = new google.maps.Marker({
                    map,
                    draggable: true,
                    animation: google.maps.Animation.DROP,
                    position: userPosition,
                    icon: "http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png"
                });

                marker.addListener("click", toggleBounce);
                var infoWindow = new google.maps.InfoWindow({
                    content: "<h3>Locatia mea ! </h3>"
                });
                marker.addListener('click', function () {
                    infoWindow.open(map, marker);
                });
            }
            addUserLocationMarker();
        }

        let neighborhoods = [];

        function callback(results, status) {
                if (status == google.maps.places.PlacesServiceStatus.OK) {
                    for (var i = 0; i < results.length; i++) {
                        var place = results[i];
                        // createMarker(results[i]);
                        drop(results);
                    }
                }
            }

        let markers = [];

        function drop(neighborhoods) {
                clearMarkers();
                for (let i = 0; i < neighborhoods.length; i++) {
                    addMarkerWithTimeout(neighborhoods[i], i * 200);
                }
            }

        function addMarkerWithTimeout(place, timeout) {
                window.setTimeout(() => {
                    var marker = new google.maps.Marker({
                        map,
                        position: place.geometry.location,
                        animation: google.maps.Animation.DROP,

                    });
                    google.maps.event.addListener(marker, "click", () => {
                        infowindow.setContent('<h2>' + place.name + '</h2>');
                        infowindow.open(map, marker);
                    }),
                        marker.addListener("click", toggleBounce);
                    markers.push(marker);
                }, timeout);
            }

        function clearMarkers() {
            for (let i = 0; i < markers.length; i++) {
                markers[i].setMap(null);
            }
            markers = [];
        }

        function toggleBounce() {
            if (marker.getAnimation() !== null) {
                marker.setAnimation(null);
            } else {
                marker.setAnimation(google.maps.Animation.BOUNCE);
            }
        }

        function ipLookup() {
            $.get('https://api.userinfo.io/userinfos', function (r) {
                showUserDetails(r.position.latitude, r.position.longitude, r);
            });
        }
    </script>
2 Answers

With the Places Library (as part of the Maps Javascript API) when doing a text search, you can omit the query parameter if you provide a type, as explained in the docs.

But the type only supports one type. So you will have to make 2 separate requests, one with pharmacy type and one with hospital and add your markers accordingly. Not a big deal I would say.

You could probably omit the type and use something like hospital, pharmacy as the text query but the results might not be of the same quality (from my tests, it doesn't return as many places and/or all relevant places). So the best option IMO is to make separate queries. You will be billed accordingly, of course.

Example:

Create your 2 request objects

var request_hospital = {
  location: userPosition,
  radius: '2000',
  type: 'hospital'
};

var request_pharmacy = {
  location: userPosition,
  radius: '2000',
  type: 'pharmacy'
};

Then you would probably need to process the results in a different callback so that you can process hospital and pharmacy markers accordingly

service.textSearch(request_hospital, callback_hospital);
service.textSearch(request_pharma, callback_pharma);

Alternatively, as you would not search for any particular text but only make a request based on place type, you can also use nearbySearch instead of textSearch.

service.nearbySearch(request_hospital, callback_hospital);
service.nearbySearch(request_pharma, callback_pharma);

You should try both and see which of the 2 services return the best results for you. See Nearby Search requests.

The most reliable way to get results for pharmacies and hospitals, is to make two different requests, one for pharmacies and one for hospitals. To label the markers differently, pass the appropriate label into the callback function.

request for pharmacies:

var requestF = {
    location: userPosition,
    radius: '2000',
    query: 'pharmacy',
}; 
function callbackF(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      // createMarker(results[i]);
      drop(results, "F");
    }
  }
}
service.textSearch(requestF, callbackF);

request for hospitals:

var requestH = {
    location: userPosition,
    radius: '2000',
    query: 'hospital',
};
function callbackH(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      // createMarker(results[i]);
      drop(results, "H");
    }
  }
}
service.textSearch(requestH, callbackH);

updated drop function:

function drop(neighborhoods, label) {

  clearMarkers();

  for (let i = 0; i < neighborhoods.length; i++) {
    addMarkerWithTimeout(neighborhoods[i], label, i * 200);

  }
}

updated addMarkerWithTimeout function:

function addMarkerWithTimeout(place, label, timeout) {
  window.setTimeout(() => {
    var marker = new google.maps.Marker({
      map,
      position: place.geometry.location,
      animation: google.maps.Animation.DROP,
      label: label
    });
    google.maps.event.addListener(marker, "click", () => {
        infowindow.setContent('<h2>' + place.name + '</h2>');
        infowindow.open(map, marker);
      }),
      marker.addListener("click", toggleBounce);
    markers.push(marker);
  }, timeout);
}

proof of concept fiddle

screenshot of resulting map

code snippet:

let map;
let service;
let infowindow;
let userPosition = {
  lat: 40.7127753,
  lng: -74.0059728
}

function initialize() {
  infowindow = new google.maps.InfoWindow();
  //Map options
  var options = {
    center: userPosition,
    zoom: 15,
    // disableDefaultUI: true,
  }
  //New map
  map = new
  google.maps.Map(document.getElementById("map"), options);

  var requestF = {
    location: userPosition,
    radius: '2000',
    query: 'pharmacy',
  };

  service = new google.maps.places.PlacesService(map);
  service.textSearch(requestF, callbackF);

  var requestH = {
    location: userPosition,
    radius: '2000',
    query: 'hospital',
  };
  service.textSearch(requestH, callbackH);

  function addUserLocationMarker() {
    marker = new google.maps.Marker({
      map,
      draggable: true,
      animation: google.maps.Animation.DROP,
      position: userPosition,
      icon: "http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png"
    });

    marker.addListener("click", toggleBounce);
    var infoWindow = new google.maps.InfoWindow({
      content: "<h3>Locatia mea ! </h3>"
    });
    marker.addListener('click', function() {
      infoWindow.open(map, marker);
    });
  }
  addUserLocationMarker();
}

function callbackF(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      // createMarker(results[i]);
      drop(results, "F");
    }
  }
}

function callbackH(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      // createMarker(results[i]);
      drop(results, "H");
    }
  }
}

let markers = [];

function drop(neighborhoods, label) {

  clearMarkers();

  for (let i = 0; i < neighborhoods.length; i++) {
    addMarkerWithTimeout(neighborhoods[i], label, i * 200);

  }
}

function addMarkerWithTimeout(place, label, timeout) {
  window.setTimeout(() => {
    var marker = new google.maps.Marker({
      map,
      position: place.geometry.location,
      animation: google.maps.Animation.DROP,
      label: label
    });
    google.maps.event.addListener(marker, "click", () => {
        infowindow.setContent('<h2>' + place.name + '</h2>');
        infowindow.open(map, marker);
      }),
      marker.addListener("click", toggleBounce);
    markers.push(marker);
  }, timeout);
}

function clearMarkers() {
  for (let i = 0; i < markers.length; i++) {
    markers[i].setMap(null);
  }
  markers = [];
}

function createMarker(place) {
  var marker = new google.maps.Marker({
    map,
    position: place.geometry.location,
    animation: google.maps.Animation.DROP,
    // place: AnimationEffect,
  });
  google.maps.event.addListener(marker, "click", () => {
    infowindow.setContent(place.name);
    infowindow.open(map, marker);
  });
  marker.addListener("click", toggleBounce);
}

function toggleBounce() {
  if (marker.getAnimation() !== null) {
    marker.setAnimation(null);
  } else {
    marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>

<head>
  <title>Place Searches</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=places&v=weekly" defer></script>
  <!-- jsFiddle will insert css and js -->
</head>

<body>
  <div id="map"></div>
</body>

</html>

Related