この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

位置情報に基づく SOQL クエリ

位置情報に基づく SOQL クエリを使用すると、Salesforce に保存されている位置情報の値を比較したり照合したりできます。倉庫と店舗の間の距離など、2 つの位置情報値の間の距離を計算できます。また、位置情報の値と固定経度・緯度座標の間の距離を計算することもできます。たとえば、倉庫とサンフランシスコが位置する緯度・経度 (37.775°, -122.418°) の間の距離を計算できます。

地理位置情報カスタム項目種別を使用すると、位置情報の値を保存する項目を作成できます。地理位置情報項目では、緯度と経度に基づいて場所を識別します。Salesforce オブジェクトの標準住所にも地理位置情報項目が含まれており、(値が入力されていれば) 同じように使用できます。ただし、いくつかの制限があります。どちらの種別でも、場所を比較したり照合したりできます。たとえば、最も近い 10 件の取引先を見つけることができます。

詳細と考慮事項については、『Salesforce オブジェクトリファレンス』「複合項目」を参照してください。

位置情報に基づく SOQL クエリに対応している項目種別

SOQL では、GEOLOCATION 関数を使用して、緯度と経度に単純な数値を指定できます。これらの値は、標準数値項目、ユーザー入力、計算値などから取得できます。地理位置情報項目の個々のコンポーネントから取得することもできます。この項目では、緯度と経度の両方を 1 つの論理項目に格納しています。地理コードサービスによって標準住所の地理位置情報項目が入力される場合は、住所から直接、緯度と経度の値を使用することもできます。

SOAP API および REST API を使用して作成された SOQL では、地理位置情報コンポーネントを含む住所項目など、地理位置情報項目を、SOQL ステートメント内で直接使用することもできます。これにより多くの場合、SOQL ステートメントが簡素化されます。複合項目は、SOAP API および REST API を使用して作成された SOQL クエリのみで使用できます。

SELECT 句

場所が地理位置情報項目または住所項目に保存されているレコードを、個々の緯度および経度の値として取得するには、通常の「__c」の代わりに「__latitude__s」または「__longitude__s」を項目名に追加します。次に例を示します。
1SELECT Name, Location__latitude__s, Location__longitude__s 
2FROM Warehouse__c
このクエリは、カスタムオブジェクト Warehouse に保存されているすべての倉庫を検索します。検索結果には、各倉庫の緯度と経度の値が表示されます。緯度および経度のコンポーネントを個々に選択するには、Location__c で個別の項目コンポーネントを使用します。
SOAP API および REST API を使用して実行される SOQL は、個々の要素ではなく複合項目を選択できます。複合項目は、プリミティブ値ではなく構造化データとして返されます。次に例を示します。
1SELECT Name, Location__c 
2FROM Warehouse__c
このクエリは、前のクエリと同じデータを取得します。ただし Location__c 項目は地理位置情報の複合項目であるため、その結果は 2 つのプリミティブ値で構成されます。以下に示すのは、REST API 要求の結果のサンプルです。
1{
2  "totalSize" : 10,
3  "done" : true,
4  "records" : [ {
5    "attributes" : {
6      "type" : "Warehouse__c",
7      "url" : "/services/data/v30.0/sobjects/Warehouse__c/a06D00000017O4nIAE"
8    },
9    "Name" : "Ferry Building Depot",
10    "Location__c" : {
11      "latitude" : 37.79302,
12      "longitude" : -122.394507
13    }
14  }, {
15    "attributes" : {
16      "type" : "Warehouse__c",
17      "url" : "/services/data/v30.0/sobjects/Warehouse__c/a06D00000017O4oIAE"
18    },
19    "Name" : "Aloha Warehouse",
20    "Location__c" : {
21      "latitude" : 37.786108,
22      "longitude" : -122.430152
23    }
24  }, 
25  ...
26  ]
27}

WHERE 句

クエリの WHERE 句に距離条件を指定し、場所が特定の半径内または半径外にあるレコードを取得します。適切な距離条件を作成するには、以下の関数を使用します。
DISTANCE
2 つの場所の距離をマイル単位またはキロ単位で計算します。
使用方法: DISTANCE(mylocation1, mylocation2, 'unit')mylocation1mylocation2 に、2 つの場所項目、または 1 つの場所項目と GEOLOCATION 関数で返された値を指定します。unit を mi (マイル) または km (キロ) に置き換えます。

場所項目と GEOLOCATION 値を使用する場合、場所項目は最初の変数、GEOLOCATION は 2 番目の変数でなければなりません。GEOLOCATION が最初の変数の場合、クエリは MALFORMED_QUERY エラーになります。

メモ

GEOLOCATION
指定された緯度と経度に基づいて地理位置情報を返します。DISTANCE 関数と併用する必要があります。
使用方���: GEOLOCATION(latitude, longitude)latitudelongitude に、対応する地理位置情報の数値コード値を指定します。
2 つの項目値を比較するか、1 つの項目値と固定の場所を比較します。次に例を示します。
1SELECT Name, Location__c 
2FROM Warehouse__c 
3WHERE DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi') < 20

ORDER BY 句

ORDER BY 句で距離条件を使用して、距離を基準にレコードを並べ変えます。次に例を示します。
1SELECT Name, StreetAddress__c 
2FROM Warehouse__c 
3WHERE DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi') < 20 
4ORDER BY DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi')
5LIMIT 10
このクエリは、カスタムオブジェクト Warehouse にある倉庫のうち、地理位置情報 37.775°, -122.418° (サンフランシスコ) から 20 マイル以内にある倉庫を最大 10 件見つけます。結果には、各倉庫の名前と住所が含まれますが、地理座標は含まれません。最も近い倉庫がリストの一番上に表示され、最も遠い倉庫が一番下に表示されます。

SOQL が Null の位置情報の値を処理する方法

地理位置情報項目は、地球上のある地点を示すために緯度と経度の値を組み合わせる複合項目です。null 値は、緯度と経度の両方が null の場合にのみ有効です。

地理位置情報項目値が無効なレコードでは、緯度と経度の両方の値が、SOQL の WHERE DISTANCE()ORDER BY の句で使用された場合に Null として処理されます。緯度または経度のどちらかが Null である地理位置情報項目を持つレコードは、項目が設定されていないものとして処理されます。

複合地理位置情報項目を SELECT 句で使用する場合、無効な地理位置情報の値には null が返されます。次に例を示します。
1SELECT Name, Location__c 
2FROM Warehouse__c 
3LIMIT 5
この表にある値は API コールから返されます。
名前 Location__c
Ferry Building Depot null
Aloha Warehouse (37.786108,-122.430152)
Big Tech Warehouse null
S H Frank & Company null
San Francisco Tech Mart (37.77587,-122.399902)
この結果には、地理位置情報の値として 3 つの null が含まれています。どの値が実際に null で、どの値が無効なデータであるかを判断することはできません。
同じ地理位置情報項目の個別の項目コンポーネントを SELECT 句で使用すると、これまでと同様に保存された値が返されます。null 以外の場合はその値で返され、null の場合は null 値として返されます。次に例を示します。
1SELECT Name, Location__latitude__s, Location__longitude__s 
2FROM Warehouse__c 
3LIMIT 5
これらの値はクエリ結果のサンプルです。
名前 Location__latitude__s Location__longitude__s
Ferry Building Depot null -122.394507
Aloha Warehouse 37.786108 -122.430152
Big Tech Warehouse null null
S H Frank & Company 37.763662 null
San Francisco Tech Mart 37.77587 -122.399902
この結果では、実際に null であるのは 1 つの地理位置情報項目のみです。他の 2 つは部分的に null であるため、無効です。

DISTANCE の計算に使用する数式項目を作成するときは、[空白項目の処理] セクションの [空白項目を空白として処理] を選択します。[空白項目を 0 として処理] を選択した場合、地理位置情報項目に Null 値があると、赤道がグリニッジ子午線と交差する位置 (0°, 0°) を基準に距離が計算されます。レコード詳細ページでは、[空白項目を 0 として処理] に設定されている DISTANCE 数式項目に Null 値の地理位置情報の値があると、数式項目が空白になります。

SOQL による距離の計算と比較の方法

DISTANCE 関数は、半正矢 (大円) の距離計算を 0.0002% 以内に近似します。この数式では、地球は完全な球体だと仮定していますが、地球は実際には楕円形、つまり不規則な球体です。この仮定の誤差は、赤道を横断するときに最大 0.55% になる可能性があります。ただし緯度と進行方向にもよりますが、通常は 0.3% 以下です。

顧客の現在の場所に最も近い 10 件の店舗を計算する場合は、DISTANCE 関数を使用しても問題ありません。ただし、この関数に基づいて、サンフランシスコからシドニーまでのフライトの飛行機に燃料を補給するのはやめましょう。

また、この近似は地理位置情報と距離に「等しい」という概念がないことを意味します。位置情報や距離が等しいかどうかは確認することができません。ある場所が別の場所より遠いか近いか、またはある距離が別の距離より長いか短いかしか判断できません。2 つの場所が「同じ」であることを確認するには、その距離を浮動小数点数として扱い、その差異と許容値を比較します。たとえば、この WHERE 句は、testLocation から 25 フィート以内にある別のレコードを検索します。
1WHERE ( DISTANCE(Location__c, testLocation) < 0.05 )

距離がほぼ同じ場合は小さな誤差ですみますが、誤差によって、期待した場所が位置情報クエリの結果に含まれたり、含まれなかったりすることがあります。アプリケーションで正確な距離の計算と比較を行う必要がある場合は、自身で計算することをお勧めします。

位置情報に基づく SOQL クエリの考慮事項

位置情報に基づくクエリは、Apex の SOQL と、SOAP API および REST API でサポートされています。次の考慮事項に留意します。

  • DISTANCEGEOLOCATION は、SOQL の WHERE 句および ORDER BY 句ではサポートされますが、GROUP BY 句ではサポートされません。DISTANCESELECT 句でサポートされます。
  • DISTANCE は、論理演算子 > および < のみをサポートし、指定された半径内 (<) または外 (>) の値を返します。
  • SOQL クエリで GEOLOCATION 関数を使用する場合、地理位置情報項目を緯度および経度座標よりも前に入力する必要があります。たとえば、DISTANCE(warehouse_location__c, GEOLOCATION(37.775,-122.418), 'km') は機能しますが、DISTANCE(GEOLOCATION(37.775,-122.418), warehouse_location__c, 'km') は機能しません。
  • Apex バインド変数は、DISTANCE 関数の単位パラメーターではサポートされません。次のクエリは機能しません。
    1String units = 'mi';
    2List<Account> accountList = 
    3    [SELECT ID, Name, BillingLatitude, BillingLongitude 
    4     FROM Account 
    5     WHERE DISTANCE(My_Location_Field__c, GEOLOCATION(10,10), :units) < 10];

詳細は、『Salesforce オブジェクトリファレンス』に記載されている「複合項目の考慮事項と制限」を参照してください。