merge autocomplete results from multiple sources - javascript

I am currently getting autocomplete results from a single source. If I wanted to also get results from a second source how would I go about this, and can I add the results on the fly (if one of the sources took longer).
For example this is a form field which is autocompleted using town names from geonames.org.
http://jsfiddle.net/Q6YFx/
How would I impliment merging the results from a second source such as Google Geocode API:
geocoder.geocode( { 'address': request.term, 'region': 'GB' }, function(results, status) {
response($.map(results, function(item) {
return {
value: item.formatted_address+' (google)',
latitude: item.geometry.location.lat(),
longitude: item.geometry.location.lng()
}
}));
})
The google results are quicker to fetch, so I'd like to show these when they are ready and then when I get the geonames.org results I'd like to add these to the mix.
Thanks

This is how I did it in the end http://jsfiddle.net/ekzMN/89/

Try adapting the code from this SO post:
jQuery UI autocomplete - multiple sources

Related

Passing a List of objects between Dart and JavaScript — convert List<dynamic> to List<GeocodeResult>

I'm trying to access the Google Maps Geocoding JavaScript API from Dart.
I have this code, which uses the js package to translate to Dart:
#JS('google.maps')
library google_maps;
import 'package:js/js.dart';
#JS()
class Geocoder {
external Geocoder();
external geocode(GeocodeOptions options, void Function(List<GeocodeResult> results, String status) callback);
}
#JS()
#anonymous
class GeocodeResult {
// ...
}
... And I'm calling it from my application like this:
geocoder.geocode(
GeocodeOptions(
address: address,
region: region,
),
allowInterop((results, status) {
// ???
}),
);
The problem is with the type of the results list in the callback function:
void Function(List<GeocodeResult> results, String status)
With the type set to GeocodeResult, I get an error:
Expected a value of type List<GeocodeResult> but got one of type List<dynamic>
But if I change the type to dynamic, then my callback function in dart receives a List<NativeJavaScriptObject>.
I don't know what to do with a NativeJavascriptObject!
it's not a Map, so I can't use square brackets — result['geometry']
if I try to use List.cast<GeocodeResult>() then I get an error: dart.notNull() is not a Function
it's a dart object, so I can't just access arbitrary properties using dot notation — result.geometry
Any and all suggestions welcome, thank you.
Okay, I've got it working by converting to JSON in JavaScript and then parsing the JSON into a Map in dart:
geocoder.geocode(
GeocodeOptions(
address: address,
region: region,
),
allowInterop((results, status) {
final list = List<Map<String, dynamic>>();
results.forEach((jsObject) {
//Convert NativeJavascriptObject to Map by encoding and decoding JSON
final json = stringify(jsObject);
final map = Map<String, dynamic>.from(jsonDecode(json));
list.add(map);
});
}),
);
This uses stringify(), below, which calls JSON.stringify() from JavaScript.
#JS('JSON.stringify')
external String stringify(Object obj);

nearby places in google maps api

I have to develop a website on which user enter latitude and longitude of a particular location. based on latitude and longitude I should fetch nearby locations and display it on google maps. As of now, I displayed the nearby locations for one type eg.restaurants, Now I want to fetch more than one type using place-API.
Unfortunately, neither searching with multiple types nor excluding a type from query is possible right now. Google's policy is simply forcing people to send more requests. Sometimes people pay for things they don't want or double/triple for what they could achieve with only one query.
Although there's no searching option for second,third parameter, you can still get what you want, with of course paying for it.
This is how a regular NearbySearch request looks like;
var service = new google.maps.places.PlacesService(map);
let latLng = new google.maps.LatLng(latitude,longitude);
service.nearbySearch(
{location: latLng, radius: 500, type: ['store']},
function(results, status) {
if (status !== 'OK') return;
// results
};
});
If you want to get multiple types, you have to send a request for each type which would look like this;
var service = new google.maps.places.PlacesService(map);
let latLng = new google.maps.LatLng(latitude,longitude);
service.nearbySearch(
{location: latLng, radius: 500, type: ['store']},
function(results, status) {
if (status !== 'OK') return;
// results for store
service.nearbySearch(
{location:latLng, radius: 1500, type : ['fire_station']},
function(fireStationResult, fireStationStatus) {
// firestation results here
// and so on.
}
)
};
});
You have to use nearbySearch request in eachother's blocks since it work async.
Searching for multiple types is not currently supported by the Places API's Nearby Search.
There is an existing feature request for this: https://issuetracker.google.com/issues/112291747. I'd recommend you to comment your use-case in there and star it to receive updates.

How to get all place details from a Place Details Request using Google Places API Web Service?

I am trying to get data, like phone numbers, from a Place Details Request using The Google Places API Web Service. I am unable to get response data that is similar to the one shown in this guide, even though I'm getting the place id from the same address.
The place id I get is different from the one in the guide. My place id is 'ChIJ8UadyjeuEmsRDt5QbiDg720' and theirs is 'ChIJN1t_tDeuEmsRUsoyG83frY4'. If I use their place id I get all the data I need.
The only data I can get are: address_components, adr_address, formatted_address, geometry, icon, id, name, place_id, reference, scope, types, url, and vicinity. How can I get data like a phone number from a request?
var placesRequest = $http({
method: "post",
url: "https://maps.googleapis.com/maps/api/place/details/json?placeid=" + <my place id>+"&key=<my key>"
});
placesRequest.success(function (data) {
console.log("data", data);
});
Same problem with Google Maps JavaScript API using this code.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.866, lng: 151.196},
zoom: 15
});
google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.getDetails({
placeId: $scope.newUserData.address.place_id
}, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
if(place) {
console.log("place", place);
}
}
});
}
initMap();
The phone number is missing in the Google Places API because Google Maps doesn't have a phone number for that particular place. If you request the details for a place with a phone number on Google Maps, it will be returned.
Take a closer look at ChIJ8UadyjeuEmsRDt5QbiDg720. It's an office building called "Workplace 6" — notice that the details say it is of type premise. If you visit the Google Maps URL in the url field (https://maps.google.com/?q=Workplace+6&ftid=0x6b12ae37ca9d46f1:0x6defe0206e50de0e) you'll notice there's no phone number listed there either.
The other Place ID, ChIJN1t_tDeuEmsRUsoyG83frY4, is for one of the businesses located inside that building (Google). If you compare the address_components or formatted_address you'll see they don't have quite the same address (Google's address is floor 5 of that building).
In general, any field of a place might be absent. This happens if Google Maps doesn't know it, or if it simply doesn't apply (e.g. you won't find opening_hours on France). As the documentation for Place Details Results say:
Each result may contain the following fields:
[Emphasis mine.]

Edit an optimized Google Maps route

Desired functionality
After gathering pre-defined Start, End and intermediate Waypoints from a database, query the Google Maps API V3 to:
a) Optimize a route based on the Waypoints given.
b) Display such route on a Map. Display the optimal waypoint order.
c) Give the user the possibility to edit the order of waypoints. Please note: It is not desired to drag the waypoint´s marker to change it´s address. The desired behaviour is to have a list of waypoints as ordered by the API and then to be able to manually edit the order and update the map accordingly.
d) Save back to the database the final order after the API´s answer and the user´s possible edits.
What is currently working
Functionality described in points A and B is covered by the following code:
function initialize() {
var mapOptions = {
zoom: 8, <!-- We can also support customizable zoom levels according to the size of delivery area !-->
center: region
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directionsPanel'));
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
computeTotalDistance(directionsDisplay.getDirections());
});
calcRoute();
}
function calcRoute() {
var request = {
origin: 'Chemnitz, Germany', <!-- This will be the main address, we get it from the database. -->
destination: 'Chemnitz, Germany',
optimizeWaypoints: true,
waypoints:[{location: 'Mittweida, Germany'}, {location: 'Zwickau, Germany'}, {location: 'Dresden, Germany'}, {location: 'Freiberg, Germany'}], <!-- This will be the list of locations the truck has to visit, we get it from the database. -->
travelMode: google.maps.TravelMode.DRIVING <!-- Maps supports many types of transport, but we have to specify this is a particular vehicle. -->
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
Question
Is there any method in the API to support manual editing of the waypoint´s order after the API has optimized and displayed them?
Are there any examples of similar solutions that might help me resolve this issue?
Additional information
The reason why I need to support manual editing of the waypoint´s order is that sometimes, there are time constraints for the deliveries these stopovers represent. Therefore, occasionally the user will want to modify the stopovers order to make them more suitably delivered at a convenient time, i.e.: the end of the day, the beginning of the route in the morning, etc.
Thanks in advance for any help.
There is no built-in implementation for this, but it's not difficult to achieve it.
The order of the optimized waypoints may be retrieved via the waypoint_order-property of a route. You may use this order to create a sortable list, when the list will be re-ordered send a new request with the re-ordered waypoints and the optimizeWaypoints-option set to false

Google maps API is not using region hint [duplicate]

This question already has answers here:
Get only country specific result using google geocode api
(4 answers)
Closed 5 years ago.
I'm having problems telling the Google maps API to restrict the results from the geocoding service to a specific region.
A simple example reproducing the problem is here: http://jsfiddle.net/pqZGr/
The JavaScript code is really simple:
$(document).ready(function () {
var geocoder = new google.maps.Geocoder();
$("#name").autocomplete({
source: function (request, response) {
geocoder.geocode({ 'address': request.term, 'region': 'it' }, function (results, status) {
response($.map(results, function (item) {
return {
value: item.formatted_address
}
}));
})
}
});
});
I also specified the API URL as http://maps.google.com/maps/api/js?region=it&language=it&sensor=false besides the 'region': 'it' in the request.
The problem is the addresses returned by Google are not restricted (nor hinted) to Italy
For example if you search mil (the begininning of Milano) I get Circondario di Miltenberg, Germania and Milion, Alemdar Mh., 34122 Istanbul/Provincia di Istanbul, Turchia and reka Mil', Sacha-Jacuzia, Russia.
It's returning results (also, only three?) from all over the world, an nothing from Italy (even when there are multiple cities matching mil).
What am I doing wrong?
As a side note, is it possible to restrict the search only to the cities, and not to full addresses?
Thanks in advance.
It sounds like you really should be using the Google Places Autocomplete API standalone or built in to the Google Maps API.
The geocoding service isn't designed for autocomplete queries, and won't return the kind of results you're looking for. The region parameter is a hint like you said, but it's not a restriction so if there is no suitable "mil" in Italy, or there is a much better match elsewhere you'll get those results.
There's no way to restrict the results to just cities.
If you are using Google geocoder autocomplete with jQuery UI, you can edit one line in ui.geo_autocomplete.js, line 46, and add your region. It's not 100% precise, but will reduce the number of found addresses:
this.options._geocoder.geocode({'address': _address}, function(_results, _status)
Replace with:
this.options._geocoder.geocode({'address': _address + ' YOUR_REGION_HERE'}, function(_results, _status)

Categories

Resources