Zip code radius search using Google Geocoder API - meteor

Here is a link to the same question.
I would however like to have this question answered using Google Geocode.
Can someone please provide me with the code to do the following, using Meteor and Blaze.
Enter zip code and return array of zip codes within 10 kilometers of that zip code.
Search collection users for fields profile.zipcode and display users matching zip codes in the array.
Thank you very much!

The Geocoder gets you the location from the text string, now you have to pass this location information to your places functionality. I have wrapped the google places code inside a function and call it from geocoder.
var address = '12 Crest View Ct';
geocoder.geocode({'address': address},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK){
loc = results[0].geometry.location;
var bounds = new google.maps.LatLngBounds();
document.write(bounds.extend(results[0].geometry.location));
map.fitBounds(bounds);
new google.maps.Marker({
position:results[0].geometry.location,
map: map
});
place(loc); //here is the function call
}
}
);

Related

Google Maps API Text Search Request

I'm new to javascript and I'm working on a project which needs to google maps.
I need to use the text search function to find nearby veterinary request a postcode does not work and I have several questions.
Do I need an API key to use the service places?
I Copied the code documentation google maps but don't understand the callback function and i don't know if something I'm doing is wrong.
If anyone has any idea what's wrong with the code, I would greatly appreciate your response.
This is my code:
<script src="https://maps.googleapis.com/maps/api/js?callback=ini&sensor=false&libraries=places"></script>
<script type="text/javascript">
var map;
var vet= " veterinarys";
ini();
function ini()
{
var mapOptions =
{
center: new google.maps.LatLng(37.7831, -122.4039 ),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map"), mapOptions);
var request =
{
radius: '500',
query: vet,
type: ['veterinary_care']
};
service = new google.maps.places.PlacesService(map);
service.textSearch(request, callback);
}
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]);
}
}
}
</script>
API key is optional, but you have to pay attention to this note.
The Google Maps JavaScript API does not require an API key to function correctly. However, we strongly encourage you to load the Maps API using an APIs Console key which allows you to monitor your application's Maps API usage.
Callback parameter in the script URL is required if you load resource asynchronously. In that case as soon as Google Maps script will be loaded it will call your function. In your case to start use it you should add async attribute to the <script> tag and remove direct ini() function call from the code. Here you find documented explanation for callback param
Your code doesn't work because you specify radius param which requires location to be specified as well. It should work if you will add the same location to the request object as center param in mapOptions. Just check available options description.
You got the rest of the help from #Mihails Boturins's answer. I will answer for the question you asked in your last comment.
There is no such createMarker function defined in you code. You have to create that function just like this

Google map places API getPlace() only return name attribute for some addresses

I have an address search box using the google map autocomplete library:
var autocompleter = new google.maps.places.Autocomplete(item);
There is an odd occasion that an address only returns a name attribute:
Object {name: "138 Manukau Road, Pukekohe, New Zealand"}
But other addresses are giving more data, such as:
Object {address_components: Array[7], adr_address: "<span class="street-address">430 Queen St</span>, …n>, <span class="country-name">New Zealand</span>", formatted_address: "430 Queen St, Auckland, Auckland 1010, New Zealand", geometry: Object, icon: "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png"…}address_components: Array[7]adr_address: "<span class="street-address">430 Queen St</span>, <span class="extended-address">Auckland</span>, <span class="locality">Auckland</span> <span class="postal-code">1010</span>, <span class="country-name">New Zealand</span>"formatted_address: "430 Queen St, Auckland, Auckland 1010, New Zealand"geometry: Objecthtml_attributions: Array[0]icon: "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png"id: "00fce9b1c43ac960068949cbf32eecb587b0b020"name: "430 Queen St"place_id: "ChIJQfHW8OVHDW0RyHgQRLy8fKc"reference: "CqQBlgAAAIDnkWNQ4cmU624FV6l_bAxmI27czZoytmzrrEWVaXgR5LcZuFqt1cL3WIMzoWhmZNhftRzhLUVwpFjqmw3qwKIqugj02HrvU5x6PtUvepPNPV-08pin_PvRU-__mMMH3N2vILIOLM_AnYFMqNG5MArF4ChZXJxZj6vk7PI3ORJe1W6QjIXoPgesL379E4WUCjrZ0fjv3KgqzB-G4f-8A5MSEN5S47-QZqkY5sl37cIQFWQaFLg4InSVLpYGg8n1gGO958TcA4UK"scope: "GOOGLE"types: Array[1]url: "https://maps.google.com/maps/place?q=430+Queen+St,+Auckland,+Auckland+1010,+New+Zealand&ftid=0x6d0d47e5f0d6f141:0xa77cbcbc441078c8"vicinity: "Auckland"__proto__: Object
I have found a similar issue which raised by someone in 2012, and looks like it has not been attended.
This problem was happening intermittently for me and usually out of the blue.
Turns out that if you get a result from Autocomplete with only a name property, you can use the google.maps.places.AutocompleteService to finish the job.
For example, call this if you only get a name back (sending the input element in el)
function getPlace(result, el, callback) {
var autocompleteService = new google.maps.places.AutocompleteService();
if (result.name.length > 0) {
var d = { input: result.name, offset: result.name.length };
autocompleteService.getPlacePredictions(d, function (list, status) {
if (list == null || list.length == 0) callback(null);
var placesService = new google.maps.places.PlacesService(el);
var ref = { 'reference': list[0].reference }
placesService.getDetails(ref, function (detailsResult, placesServiceStatus) {
if (placesServiceStatus == google.maps.GeocoderStatus.OK) {
callback(detailsResult);
}
else {
callback(null);
}
});
});
}
}
This helped me a lot
http://plnkr.co/edit/GF3nM3XfYX9El2w11pGo?p=preview
Surprisingly the very same address now returning correct data, google must be watching these errors and fix them as soon as possible.
Maybe the google service is not able to geocode your address and only return to you the name of the address found. The reason could be that the service has no aditional data to give you for those adress.
You can just not show those incomplete address to the user or try to geocode that address by another service like OSM Geocoder
http://wiki.openstreetmap.org/wiki/Nominatim
From Google Maps Autocomplete Reference:
Returns the details of the Place selected by user if the details were
successfully retrieved. Otherwise returns a stub Place object, with
the name property set to the current value of the input field.
So the answer is that the getPlace method is just failing for specific places. Not sure how to solve this, but gets us one step closer to the answer.
EDIT: FIXED IT!
For my app, I'm loading multiple libraries for google maps (geometry and places). Switching the order that the libraries were loaded fixed the issue, and I don't know why.
Change:
maps.googleapis.com/maps/api/js?v=3&key=[KEY]&libraries=geometry,places
to
maps.googleapis.com/maps/api/js?v=3&key=[KEY]&libraries=places,geometry

Geocoding in Google Earth API using Maps V3

I have developed an application a while ago using GE plugin. In that application, I use the Geocode function which depends of course on (maps, 2.xx). With the deprecation of Google Maps V2, this part of the code is no longer working. My code is based on the sample application for geocoding in the Google Earth Demo site (http://earth-api-samples.googlecode.com/svn/trunk/examples/geocoder.html) which no longer works either.
I searched the v3 site but couldn't find a way of dealing with this. Using
google.load("maps", "3.xx");
instead of
google.load("maps", "2.xx");
simply doesn't work and I get a rejection from the Google Maps server.
The reason using google.load("maps", "3.xx"); doesn't work is that you MUST supply the sensor parameter. i.e. google.load('maps','3.6', { other_params: 'sensor=false' });
The sensor parameter of the URL must be included, and indicates
whether this application uses a sensor (such as a GPS locator) to
determine the user's location. We've left this example as a variable
set_to_true_or_false to emphasize that you must set this value to
either true or false explicitly.
See: https://developers.google.com/maps/documentation/javascript/tutorial#Loading_the_Maps_API
Anyhow, I made a working example of using the Google Maps V3 Geocoder with the Earth Api for you to see how it works.
Also here is a code example that geocodes the term "New York" and moves to the first result found once the plugin and maps api have loaded (just in case jsfiddle disappears in future...)
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('earth', '1');
google.load('maps','3.6', { other_params: 'sensor=false' }); // or true
var ge = null; // GEPlugin
var geocoder = null; // GClientGeocoder
var init = function() {
google.earth.createInstance('map3d', initCallback, failureCallback);
};
var initCallback = function(object) {
ge = object;
geocoder = new window.google.maps.Geocoder(); //v3 Geocoder
ge.getWindow().setVisibility(true);
// for example: geocode New York
geocode("New York");
};
var failureCallback = function(error) {
alert("Plugin Error: " + error);
};
var geocode = function(address) {
geocoder.geocode({ 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// do something with the result, such as flying to it...
var point = results[0].geometry.location;
var lookat = ge.createLookAt('');
lookat.set(point.lat(), point.lng(), 100, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, 0, 1000);
ge.getView().setAbstractView(lookat);
} else {
alert("Geocode Error: " + status);
}
});
};
google.setOnLoadCallback(init);
</script>
You could load the v3 script and modify the geocoding parts of your project, but if all you need is geocoding you can call the Geocoding web service directly.
Or, you can keep your existing code: Most old v2 code actually still works, it's just that GLatLng.x and y were never supported. So instead of point.x and point.y, use point.lng() and point.lat() respectively.

How to search for cities in an area using Google Maps v3?

I tried to search for all cities within a visible map's bounds. How can I do that?
Below is what I tried to do:
$.fn.gmap3.geocoder.geocode({ 'address': 'Georgia' }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
globalMap.setCenter(results[0].geometry.location);
var resultBounds = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast()
);
globalMap.fitBounds(resultBounds);
// get cities in the map
var service = new google.maps.places.PlacesService(globalMap);
var request = {
bounds: resultBounds,
types: ['locality']
};
service.search(request, function (results, status) {
debugger;
});
}
});
But the result is ZERO_RESULTS. Maybe the reason is that the results are restricted to a radius of 50.000 meters?
Anyone knows how to solve my problem? Thanks a lot.
--UPDATE--
Thank, Sean, for reading my post carefully and give detail feedback.
This is how I refer to the lib:
src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"
I also added more detail to the geocode function to get more precise result. But I still don't get the results I want.
Check the list in this page: https://developers.google.com/places/documentation/supported_types, I realize that almost all items in the first list returns values but not for the second list. The only item return value is 'political' and it returns only 1 instead of 20.
This is my code after modifing:
this.setCenterByAddress = function (address, region) {
$.fn.gmap3.geocoder.geocode({ 'address': address, 'region': region }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
globalMap.setCenter(results[0].geometry.location);
var resultBounds = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast()
);
globalMap.fitBounds(resultBounds);
// get cities in the map
var service = new google.maps.places.PlacesService(globalMap);
var request = {
bounds: resultBounds,
types: ['country',
'administrative_area_level_1',
'administrative_area_level_2',
'administrative_area_level_3',
'colloquial_area',
'country',
'floor',
'geocode',
'intersection',
'locality',
'natural_feature',
'neighborhood',
'political',
'point_of_interest',
'post_box',
'postal_code',
'postal_code_prefix',
'postal_town',
'premise',
'room',
'route',
'street_address',
'street_number',
'sublocality',
'sublocality_level_4',
'sublocality_level_5',
'sublocality_level_3',
'sublocality_level_2',
'sublocality_level_1',
'subpremise',
'transit_station']
};
service.search(request, function (results, status) {
debugger;
});
}
});
}
MORE INFO: The same value return even when location and radius is used. And I use free map and receive "OVER_QUERY_LIMIT" all the time.
You shouldn't be limited to 50,000 meters unless you use the location and radius option, which you are not; you are using bounds. I suggest backing out a level and digging into the results that are returned from the starting call to geocode, because your usage of the PlacesService appears to be correct. What are the values internal to the resultBounds object? I also notice that you aren't using region biasing when you call the geocoder and it may be that "Georgia" is not sufficiently specific. For example, do you mean the region within the Russian Federation or the US state? And I'm not sure what URL you are using to load the Google Maps API & places library, but that could also be effecting your results.
I'd double-check the results coming back from the geocoder, because unless I am missing something, it looks like your basic approach is sound.
You can't return more than two near by localities around a particular latitude-longitude with Geocoding API/Places API
Please see this thread on Google Places API forum
This is not possible with the Google Places API as political results
such as locality, neighbourhood and sublocality are returned to
identify the area of the request and are limited to two per request.

Automatically Finding Appropriate Zoom for Geocoding Result

I'm using Google Maps and Google Geocoding service for my location service application. I use Google Geocoding service for translating address to lat/lng position. My problem is how to automatically find an appropriate zoom for a certain address like the maps.google.com does.
For example, when I search a street in maps.google.com (e.g. Cisitu Baru, Bandung), it will show the street in smaller zoom. When I search a region (e.g. Bandung), it will show larger zoom. And a larger zoom for province (e.g. Jawa Barat / West Java), and so on.
I have tried both
var geocoder = new google.maps.Geocoder();
geocoder.geocode( {
'address': someAddress
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.dir(results);
//cut
map.panToBounds(results[0].geometry.bounds); //setting bound
//cut
}
});
and
//cut
map.panToBounds(results[0].geometry.viewports); //setting bound
//cut
(Honestly, I still don't know what's the difference between bounds and viewport and what are their uses from code.google.com/apis/maps/documentation/javascript/geocoding.html)
but both still don't display the map in appropriate zoom.
Right now, I use a small hack like this
var tabZoom = {
street_address: 15,
route: 15,
sublocality: 14,
locality: 13,
country: 10
};
//cut
map.setCenter(results[0].geometry.location);
if (tabZoom[results[0].types[0]] != undefined){
map.setZoom(tabZoom[results[0].types[0]]);
} else {
map.zetZoom(10);
}
//cut
Is there other solution? (Or anything from Google Map API that I don't know yet?)
Thanks!
use GLatLngBounds class
an example:
// map: an instance of GMap2
// latlng: an array of instances of GLatLng
var latlngbounds = new GLatLngBounds( );
for ( var i = 0; i < latlng.length; i++ )
{
latlngbounds.extend( latlng[ i ] );
}
map.setCenter( latlngbounds.getCenter( ), map.getBoundsZoomLevel( latlngbounds ) );
^
The trick is to add the list of all points that need to be visible on the map simultaneously into a GLatLngBounds object. The Google Maps API can do the rest of the maths.
or in v3 you can use LatLngBounds class (similar to GLatLngBounds in v2), link: http://code.google.com/apis/maps/documentation/javascript/reference.html#LatLngBounds
for an example
better check this out: http://unicornless.com/code/google-maps-v3-auto-zoom-and-auto-center
use viewport of the result geometry. if your search result does not have specific bounds, you will get an error with geometry.bounds
viewport gives you best view for the result.
map.fitBounds(results[0].geometry.viewport);

Resources