No Results
Search Tips:
- Please consider misspellings
- Try different search keywords
Apex での地図データの作成例
カスタムクエリの実行、ユーザの現在の場所近くの場所の検索、結果の絞り込みおよび変換を行う場合や、Visualforce の標準コントローラから返される結果を使用できない場合には、Apex で場所データを作成します。
Apex コードでは、返される結果を完全に制御して、地図やマーカーに使用できます。また、Apex を使用して、Salesforce 外から結果を返すこともできます。
次に、ユーザの現在の場所に最も近い最大 10 個の倉庫を表示するページを示します。
このコードにより、次の地図が作成されます。
1<apex:page controller="FindNearbyController" docType="html-5.0" >
2
3 <!-- JavaScript to get the user's current location, and pre-fill
4 the currentPosition form field. -->
5 <script type="text/javascript">
6 // Get location, fill in search field
7 function setUserLocation() {
8 if (navigator.geolocation) {
9 navigator.geolocation.getCurrentPosition(function(loc){
10 var latlon = loc.coords.latitude + "," + loc.coords.longitude;
11 var el = document.querySelector("input.currentPosition");
12 el.value = latlon;
13 });
14 }
15 }
16 // Only set the user location once the page is ready
17 var readyStateCheckInterval = setInterval(function() {
18 if (document.readyState === "interactive") {
19 clearInterval(readyStateCheckInterval);
20 setUserLocation();
21 }
22 }, 10);
23 </script>
24
25 <apex:pageBlock >
26 <!-- Form field to send currentPosition in request. Make it
27 an <apex:inputHidden> field to hide it. -->
28 <apex:pageBlockSection >
29 <apex:form >
30 <apex:outputLabel for="currentPosition">Find Nearby</apex:outputLabel>
31 <apex:input size="30"
32 html-placeholder="Attempting to obtain your position..."
33 id="currentPosition" styleClass="currentPosition"
34 value="{!currentPosition}" />
35 <apex:commandButton action="{!findNearby}" value="Go!"/>
36 </apex:form>
37 </apex:pageBlockSection>
38
39 <!-- Map of the results -->
40 <apex:pageBlockSection rendered="{!resultsAvailable}" title="Locations">
41 <apex:map width="600px" height="400px">
42 <apex:repeat value="{!locations}" var="pos">
43 <apex:mapMarker position="{!pos}"/>
44 </apex:repeat>
45 </apex:map>
46 </apex:pageBlockSection>
47
48 </apex:pageBlock>
49
50</apex:page>
このページには、3 つの重要なセクションがあります。
- 先頭にある JavaScript ブロックは、ユーザに現在の場所を尋ねるブラウザの組み込み機能へのアクセス方法を示します。このコードは表示されるフォーム項目を更新しますが、非表示のフォーム項目を代わりに使用して、きわめて精度が低い未加工の緯度と経度がユーザに表示されないようにすることができます。
- 最初の <apex:pageBlockSection> には、ユーザの場所を POSTBACK 要求に送信するための簡単なフォームが含まれています。説明のため、フォームが表示されクリックを必要とする設定になっていますが、これは必須ではありません。
- 2 番目の <apex:pageBlockSection> は、わずか 5 行のコードを必要とする簡単な地図です。複雑な点は、Apex コントローラでプロパティにアクセスする {!locations} 式のみです。rendered 属性および {!resultsAvailable} 式の使用に注目してください。この式は別の Apex プロパティであり、地図に配置できる場所がなければ、この組み合わせにより地図セクションが非表示になります。
次に、上記のページをサポートする Apex コントローラを示します。
1public with sharing class FindNearbyController {
2
3 public List<Map<String,Double>> locations { get; private set; }
4
5 public String currentPosition {
6 get {
7 if (String.isBlank(currentPosition)) {
8 currentPosition = '37.77493,-122.419416'; // San Francisco
9 }
10 return currentPosition;
11 }
12 set;
13 }
14
15 public Boolean resultsAvailable {
16 get {
17 if(locations == Null) {
18 return false;
19 }
20 return true;
21 }
22 }
23
24 public PageReference findNearby() {
25 String lat, lon;
26
27 // FRAGILE: You'll want a better lat/long parsing routine
28 // Format: "<latitude>,<longitude>" (must have comma, but only one comma)
29 List<String> latlon = currentPosition.split(',');
30 lat = latlon[0].trim();
31 lon = latlon[1].trim();
32
33 // SOQL query to get the nearest warehouses
34 String queryString =
35 'SELECT Id, Name, Location__longitude__s, Location__latitude__s ' +
36 'FROM Warehouse__c ' +
37 'WHERE DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'mi\') < 20 ' +
38 'ORDER BY DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'mi\') ' +
39 'LIMIT 10';
40
41 // Run the query
42 List <Warehouse__c> warehouses = database.Query(queryString);
43
44 if(0 < warehouses.size()) {
45 // Convert to locations that can be mapped
46 locations = new List<Map<String,Double>>();
47 for (Warehouse__c wh : warehouses) {
48 locations.add(
49 new Map<String,Double>{
50 'latitude' => wh.Location__latitude__s,
51 'longitude' => wh.Location__longitude__s
52 }
53 );
54 }
55 }
56 else {
57 System.debug('No results. Query: ' + queryString);
58 }
59
60 return null;
61 }
62}このコントローラの詳細および上記の Visualforce ページでどのように動作するかを習得してください。
- Map<String,Double> 要素のリストである locations プロパティ。<apex:mapMarker> コンポーネントで直接使用できる形式で場所データが保持されます。
- ページのフォームから送信された位置情報を取得する currentPosition プロパティ。このプロパティにも、空のフォームが送信された場合の有効なデフォルト値があります。堅牢な実装にすることで、フォーム入力に対するエラーチェックが強化されます。
- Visualforce マークアップの以前の説明で記載した resultsAvailable プロパティ。
- [Go!] <apex:commandButton> を押したときにコールされる findNearby アクションメソッド。このメソッドは、カスタム SOQL クエリの実行、locations ���ロパティ形式への結果の変換など、すべての処理を行います。
<apex:mapMarker> の title 属性を使用して、追加情報 (倉庫の名前など) を表示する場合は、場所を示す地図オブジェクトとタイトル文字列を組み合わせる内部クラスを作成でき、それにより内部クラスオブジェクトのコレクションがページに返されます。