-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnominatimmatcher.js
160 lines (134 loc) · 5.27 KB
/
nominatimmatcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* Copyright (C) 2011 Klokan Technologies GmbH ([email protected])
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* USE OF THIS CODE OR ANY PART OF IT IN A NONFREE SOFTWARE IS NOT ALLOWED
* WITHOUT PRIOR WRITTEN PERMISSION FROM KLOKAN TECHNOLOGIES GMBH.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
*/
/**
* @fileoverview Class that retrieves autocomplete matches from Nominatim
* geocoder service.
*
* @author [email protected] (Petr Pridal)
*/
goog.provide('goog.ui.AutoComplete.NominatimMatcher');
goog.require('goog.net.Jsonp');
/**
* An array matcher that requests matches via JSONP.
* @param {string=} opt_url The Uri of the web service.
* @param {Object.<string, string>=} opt_payload The list of extra parameters
for the Jsonp request.
* @constructor
*/
goog.ui.AutoComplete.NominatimMatcher = function(opt_url, opt_payload) {
/**
* The url of the Nominatim instance
* @type {string}
* @private
*/
this.url_ = opt_url || 'http://open.mapquestapi.com/nominatim/v1/search';
/**
* The list of extra parameters for the Jsonp request
* @type {!Object}
* @private
*/
this.payload_ = opt_payload || {};
/**
* The Jsonp object used for making remote requests. When a new request
* is made, the current one is aborted and the new one sent instead.
* @type {!goog.net.Jsonp}
* @private
*/
this.jsonp_ = new goog.net.Jsonp(this.url_, 'json_callback');
};
/**
* Retrieve a set of matching rows from the server via JSONP and convert them
* into rich rows.
* @param {string} token The text that should be matched; passed to the server
* as the 'token' query param.
* @param {number} maxMatches The maximum number of matches requested from the
* server; passed as the 'max_matches' query param. The server is
* responsible for limiting the number of matches that are returned.
* @param {Function} matchHandler Callback to execute on the result after
* matching.
*/
goog.ui.AutoComplete.NominatimMatcher.prototype.requestMatchingRows =
function(token, maxMatches, matchHandler) {
var suffix = window['GAZETTEER_SUFFIX'] || '';
this.payload_['q'] = token + suffix;
this.payload_['format'] = 'json';
this.payload_['addressdetails'] = 1;
this.payload_['limit'] = maxMatches;
// Ignore token which is empty or just one letter
if (!token || token.length == 1) {
matchHandler(token, []);
return;
}
// If you find london
// After direct request cancel autocomplete
if (maxMatches == 1) this.oldtoken_ = token;
if (maxMatches > 1 && token === this.oldtoken_) return;
// Cancel old request when we have a new one
if (this.request_ !== null) this.jsonp_.cancel(this.request_);
this.request_ = this.jsonp_.send(this.payload_, function(e) {
// If there is one or more "place" then return only these
var places = goog.array.filter(e, function(r) {
return (r['class'] == 'place' || r['class'] == 'highway');
});
var rest = goog.array.filter(e, function(r) {
return (r['class'] !== 'place' && r['class'] !== 'highway');
});
if (places.length > 0) {
// Fix the "display_name"
goog.array.forEach(places, function(r) {
if (r['address']['country_code'] == 'us')
var country = r['address']['state']; // + ', USA';
else if (r['address']['country_code'] == 'gb')
var country = 'UK';
else if (r['address']['country_code'] == 'de')
var country = 'Germany';
else
var country = r['address']['country'];
var town = (r['address']['city'] ? r['address']['city'] :
(r['address']['town'] ? r['address']['town'] :
(r['address']['village'] ? r['address']['village'] :
r['address']['hamlet'])));
if (r['type'] == 'suburb')
var s = r['address']['suburb'] + (town ? ', ' + town : '') +
', ' + country;
if (r['type'] == 'city' ||
r['type'] == 'town' ||
r['type'] == 'village' ||
r['type'] == 'hamlet')
var s = town + ', ' + country;
else if (r['osm_type'] == 'way')
var s = (r['address']['road'] ?
r['address']['road'] : r['address']['pedestrian']) +
', ' + town + ', ' + country;
else if (r['type'] == 'house')
var s = r['address']['road'] + ' ' + r['address']['house_number'] +
', ' + town + ', ' + country;
else
var s = r['display_name'];
r['display_name'] = s;
});
matchHandler(token, goog.array.concat(places, rest));
} else {
matchHandler(token, e);
}
});
};