Google Places APIを使用して、JavaScriptを使用して住所をオートコンプリートしています
入力ボックスに住所のユニット番号と番地を入力すると、提案ドロップダウンに結果が表示されますが、住所を選択すると、アクション「place_changed」イベントのリスナーには、「subpremise」タイプのaddress_componentの住所がありません。 'formatted_addressプロパティでさえ、ユニット番号は含まれていません。ただし、'番地 '、'都市 '、'国 'などの他の詳細は含まれています。
例:オーストラリアに国を制限して「1403/648BourkeStreet」と入力した場合。ドロップダウンに5つの結果が表示され、最初の結果は「1403/648 Bourke street、Melbourne、Australia」ですが、このオプションを選択すると、place_changeイベントリスナーに表示されるのは「648Bourke street、Melbourne、Australia」だけです。
この問題は断続的ですが、一部のユニットアドレスでは機能しますが、他のユニットアドレスでは失敗します。どんな提案でも大歓迎です!!
グーグルが住所が本物であることを検証しているように私には思えます(彼らが場所データベースを最後に更新したときは少なくとも本物です-私は政府の記録で推測します)。問題は、新しい「サブプレミス」アドレスが作成される場所で常に細分化が行われていることであり、これらの検索はより頻繁に行われているようです。オートコンプリートの提案として「無効な」アドレスを許可するが、結果を制限するのは奇妙なことです。
以下のシドニーの住所を検索すると、「subpremise」と「street_number」が返されます。
「9/321ピットストリート、シドニー、ニューサウスウェールズ、オーストラリア」
以下のメルボルンの住所が「ルート」と同じくらい正確になる場合
「2/321ピットストリート、ブランズウィック、ビクトリア、オーストラリア」
最大の問題は、結果が返信のどこにもユニットまたは番地を返さないことです。
次のJSを一緒にハッキングして、ユーザーが入力したアドレスと返された結果を比較しました。 「番号」が欠落している場合は、追加されます。コードに合わせて、必要に応じてカスタマイズできます。
if (addressType == 'route') {
var regex = RegExp('^(.*)'+GPLACESSTREET.split(' ',1)[0]), // get all the user entered values before a match with the first Word from the Google result
result = regex.exec(INPUTFEILD.value);
if ( Array.isArray(result) ) {
FULLSTREETADDRESS = result[1]+''+GPLACESSTREET; // add the street name to the user-entered unit & street number
}
}
Places Autocomplete APIは、「サブプレミス」の結果をサポートするようには設計されていません。これは、しばらく前に公開課題トラッカーで報告され、回答されました https://issuetracker.google.com/35830389
サブプレミス結果のオーストラリアの住所は、street_address/premise結果の住所に「十分に近い」ように見えます(ほとんどが数字で始まります)。これにより、現在、プレイスオートコンプリートがサブプレミスの結果のように見える結果を返しますが、タイプはまだ「ルート」であることに注意してください。
http://maps.googleapis.com/maps/api/place/autocomplete/json?input=9/321%20Pitt%20Street,%20Sydney
description: "9/321 Pitt Street, Sydney NSW, Australia",
place_id: "Eig5LzMyMSBQaXR0IFN0cmVldCwgU3lkbmV5IE5TVywgQXVzdHJhbGlh",
types: ["route","geocode",],
このplace_idを使用したPlaceDetails(およびGeocoding)リクエストは、実際には正しいサブプレミスの結果を見つけます。
"result" : {
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"types" : [ "subpremise" ],
ただし、これはすべてのサブプレミスクエリで機能することは保証されていません。また、長期的にはこの特定のクエリでも機能することは保証されていません。
より信頼性の高いアプローチは、GeocodingAPIを使用して予測の「説明」を検索することです。
"results" : [
{
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
],
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"place_id" : "Eik5LzMyMSBQaXR0IFN0LCBTeWRuZXkgTlNXIDIwMDAsIEF1c3RyYWxpYSIdGhsKFgoUChIJkyPU0z2uEmsR-pmiK6UvZUASATk",
"types" : [ "subpremise" ]
@MountainAshのコードからのわずかな変更:
if (addressType == 'route') {
var regex = RegExp('^(.*?)'+GPLACESSTREET.split(' ',1)[0]), // get all the user entered values before a match with the first Word from the Google result
result = regex.exec(INPUTFEILD.value);
if ( Array.isArray(result) ) {
FULLSTREETADDRESS = result[1]+''+GPLACESSTREET; // add the street name to the user-entered unit & street number
}
}
RegExpに追加の?があることに注意してください。これにより、通りの名前が同じ郊外の名前で始まる場合(123 Clayton Rd、Claytonなど)をカバーするために検索が貪欲になりません。
ユニット番号を収集してストリート番号の前に追加したかったので、私の解決策は次のとおりです。
const place = this.AutoComplete.getPlace();
if (isNullOrUndefined(place)) return;
const parts = place.address_components;
const getAddressPart = part => {
const found = parts.find(p => p.types.indexOf(part) > -1);
if (found) {
return found.long_name;
}
return null;
};
const address = this.Input.current.value; // input[text] value
let streetNumber = getAddressPart("street_number");
// Regex Match associated
if (streetNumber) {
const regex = RegExp(`[^\\s,]*(${streetNumber})[^\\s,]*`);
const foundStreetNumber = regex.exec(address);
streetNumber = foundStreetNumber[0];
}
const Address = {
FullAddress: address,
StreetNumber: streetNumber,
Street: getAddressPart("route"),
Suburb: getAddressPart("sublocality"),
City: getAddressPart("locality"),
Country: getAddressPart("country"),
PostCode: getAddressPart("postal_code")
};
これにより、Google Places APIからの番地データが改善され、次のような住所に対応します。
4/33 Mokoia Rd、Birkenhead、Auckland 0626、New Zealand
Proletarska ulica 3/25、Kidričevo、スロベニア(住所の最初に番地がない場合があります)。
また、番地がない場合は動作せず、ユニット番号がない場合は値が同じになります。
グーグルはそれをサポートしていません、しかしあなたはそれをする顧客を止めることはできません!
@MountainAshと@Randellのコードに触発された完全な関数は次のとおりです。
/* Add the unit number (+ fix the street number) if required.
*
* Idea from https://stackoverflow.com/questions/17936689/google-places-autocomplete-suggestions-with-unit-no-subpremise-is-not-coming-in
*
* Test cases:
* 9/321 Pitt Street, Sydney, New South Wales, Australia <-- Google throws away the unit number
* 2/321 Pitt Street, Brunswick, Victoria, Australia <-- Google says street number = 2
* 1b/123 Clayton Road, Clayton, Victoria, Australia <-- Google says street number = 1
*/
function autofillUnitNumber(txtAutocomplete, txtUnitNumber, txtStreetNumber, txtStreetName) {
var regex = RegExp("^(.*?)\/(.*?) " + txtStreetName.value); // get all the user entered values before a match with the street name; group #1 = unit number, group #2 = street number
var results = regex.exec(txtAutocomplete.value);
if (Array.isArray(results)) { // it was in unit number/street number format
var unitNumber = results[1]; // group #1
var streetNumber = results[2]; // group #2
txtUnitNumber.value = unitNumber;
txtStreetNumber.value = streetNumber;
}
}
Googleオートコンプリートを使用して他のフォームフィールドに自動入力した後で呼び出すだけです。例:
autofillUnitNumber(
document.getElementById("txtAutocomplete"),
document.getElementById("txtUnitNumber"),
document.getElementById("txtStreetNumber"),
document.getElementById("txtStreetName"));