How to display custom places in Google Maps API search results?
Asked Answered
G

1

13

So there is this basic example of a google map with a searchbox: https://developers.google.com/maps/documentation/javascript/examples/places-searchbox

I want to accomplish something very simple. I'd like to just hardcode some locations (may be some simple array/object with their latitudes and longitudes) and then when you search for place, for example, "Washington", then those locations are displayed (with marker) if some of them are indeed inside Washington. If I search for "Africa" and some of my locations are inside africa, I want them to be displayed. And if I search for a place which has none of my locations, then they should simply be not displayed.

I also found this — https://developers.google.com/places/documentation/actions#adding_a_place. But I am not sure if that is what I should use for my purpose (or should I?). And if it is, I'm not sure how to use it — where do I send the suggested JSON data?

Thanks in advance!

Gobetween answered 23/5, 2014 at 8:12 Comment(3)
Have never used it but I would add these places, yes. Still if you add a place somewhere in Africa, I don't think searching for Africa will return these places but I might be wrong.Quackery
Well, eventually I didn't use that "adding place" functionality. I suspect it should be used for slightly different purposes. May be it is more appropriate when you want to add places which you think should become visible for all google maps users, not just ones who use your application. May be I'm wrong, though.Gobetween
Well I guess the primary purpose is to make it available to all users. But new places are moderated. And if they are not added on a global scale, they still remain available to your application. That said, you can manage places within your application and you don't need to use the add places functionality; that's for sure.Quackery
G
29

Alright, i've solved it! I'd like to share how it is done... I must say, programming world is new to me and hell it is very interesting :) And it is the first time I've used any kind of API... Here is a working example: http://codepen.io/everdimension/pen/LpfEH?editors=001

Explained:

So, first thing you gotta know is how to add markers. That can be easily found in maps API documentation. The marker is added like that:

var marker = new google.maps.Marker({ marker_properties });

Ok, so how do we add all the markers for the places you have? Well, you simply iterate through the places which have coordinates. First, let's create the places array:

var random_places = [
  ['Moscow1', 55.822083, 37.665453, 4],
  ['Moscow2', 55.604697, 37.642107, 4],
  ['Lisbon1', 38.749402, -9.120034, 4],
  ['Lisbon2', 38.708960, -9.169130, 4],
  ['NewYork1', 40.784513, -73.976630, 4],
  ['NewYork2', 40.707522, -74.037055, 4],
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

Ok, now let's iterate through these places and add a marker each time:

for (var i = 0; i < random_places.length; i++) {
    var beach = random_places[i];
    var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: beach[0],
    });
};

Ok, so this code just uses basic API functionality and should be no problem. But all the markers we've created exist on the map all the time, no matter if they are within the visible bounds or not. But we want the markers to appear only if they are within the part of the map we are looking at. Now that's exactly what my question was about. And here's how we can do it.

The key word is bounds. Turns out, with maps API we can make the following event listener:

google.maps.event.addListener(map, 'bounds_changed', function() { ... });

And the function will execute each time the bounds of the maps are changed! What we have to do is check if the markers fall within the current bounds and if they do, we'll create them. So here:

var place_markers = [];

google.maps.event.addListener(map, 'bounds_changed', function() {

    var bounds = map.getBounds();
    searchBox.setBounds(bounds); // not needed for our purpose, it adds bias to new     searches

    var NE = bounds.getNorthEast();
    var SW = bounds.getSouthWest();

    // Iterate through all places
    for (var i = 0; i < random_places.length; i++) {
            var place_arr = random_places[i];

            // Check if a place is within bounds - not best way, explained later
            if ( (NE.lat() > place_arr[1] && place_arr[1] > SW.lat()) &&
                    (NE.lng() > place_arr[2] && place_arr[2] > SW.lng()) ) {

                    var myLatLng = new google.maps.LatLng(place_arr[1], place_arr[2]);
                    var marker = new google.maps.Marker({
                            position: myLatLng,
                            map: map,
                            title: place_arr[0],
        });

        place_markers.push(marker);

    }
};

});

That's it! Now the markers only get created when they are within the visible part of the map! You may have noticed that I had also created an empty place_markers object and then had pushed all created marked into it. Why? Because we need to do one more thing. We'd want to remove all the created markers if they fall outside of current bounds! So each time the bounds are changed we would like for this code to execute:

// Remove out of bounds markers
for (var k = 0; k < place_markers.length; k++) {
  var one_marker = place_markers[k];
  if (!bounds.contains(one_marker.getPosition())) {
    one_marker.setMap(null);
  }
}

You can see that here I've used a built in bounds.contains() function to check if a created marker is within bounds. Same function can also be used when the markers are created, but I decided to leave the code like that to show the process of finding the correct solution. The main thing is that the markers are now being removed when they fall out of bounds and get created when they are within!

One more thing I have to say. It's not the only way to accomplish the task I wanted. It can be done in many other ways. I have found a step-by-step explanation of an advanced way which uses PHP and MySQL: https://developers.google.com/maps/articles/phpsqlsearch_v3

I hope this will be useful for someone who is, like me, new to google maps api.

Gobetween answered 25/5, 2014 at 12:13 Comment(3)
Good point that you posted your findings. You are right to say that it's probably not the best way of doing it, but if it fits your needs, then it's all fine. Regarding the PHP/MySQL solution, the example is a good start to get the idea but I'd strongly advise you not to use XML for the output but JSON which will be easier to handle.Quackery
When I typed "Moscow1" , it did not show me autocomplete suggestion. Same for NewYork1 and NewYork2 etc. Is it right?Hearthside
Yes, it's not supposed to show suggestions from my random_places array. The behavior I was targeting was showing the marker if it falls within the bounds of the current viewport and to unmount the marker if it falls outside of them, irrelevant of what the user searches for.Gobetween

© 2022 - 2024 — McMap. All rights reserved.