使用例と使い方

ロケーションARは開発者にGeo(位置認識)マーカーに双方向で使いやすいデジタルコンテンツを付けることを可能にします。

引き続きGeo ARの使い方を学ぶことは、その技術と生い立ちを検証し、無料のSDKトライアルにアクセスし、そして、Geo AR の参考事例を見ることができます。

Geo AR 事例

WikitudeはARの開発を2008年から続けてきました。そして、世界で最初の歩行者と車のナビゲ―ションシステムを完成させました。それは、AR画面を統合し、地図への依存をなくしたものでした。

 

10年以上前に完成させたそれは、ナビゲーションとガイダンスの世界で、将来の革新的な段階に進む、として何度も賞賛されました。

1901年にその最初の概念的な考え方が発表されたARは、きわめて短い間に広まったけれども、ロケーションARベースのモバイルゲームはそのテクノロジーを確立したのは2016年でした。

 

ぽけもんGOを聞いたことがあるでしょう?

ぽけもんGOはARの世界でビッグヒットを飛ばしただけではなく、今までに制作されたモバイルゲームの中で、実際に最も成功した物の一つです。

世界中のプレイヤーが、彼らの周りを徘徊しながら、興味のある特定の場所に張り付けられたデジタル化されたポケモンを発見するアプリを使います。ぽけもんGO Geo アプリは驚異的に記録を塗り替えました。発表されてわずか20日で1億ドルの売上を達成しました。

ポケモンGOの成功はGeo AR ゲームとロケーションベースのAR の一般的な使用の世界に扉を開き、多くの投資に動機付けを与えました。これがGeoベースのARアプリが多くの分野で見られるようになった理由です。分野は、エンターテイメント、ナビゲ―ション、小売業、観光、通信、不動産、等です。

Geo AR ゲームのアイデアと必要性は始めるための後押しになるでしょうか?簡単な3つのステップでぽけもんGOのようなアプリをどのように作るのかを学びましょう。

Geo AR:ロケーションARの技術

Geo AR 技術は、開発者に興味のある地点へデジタルコンテンツを加えることを許してきました。このことは、典型的なマーカーAR機能、イメージトラッキング(画像認識)やオブジェクトトラッキング(対象物認識)などとは異なっていることを意味しています。Geo ARは物理的なターゲットをAR実行のトリガーとして必要としないのです。

拡張現実は、特定の事前に決めた位置に張り付けられて、その地点で現れます。

スマート機器のユーザーは、3D拡張現実、ビデオ、文章、音声、リンク等の各種のコンテンツを見たり、やり取りをするために、地理的な場所をスキャンすることができます。

 

Wikitude AR SDKは、地理的な参照データ出作動する使いやすい機能包含しています。実例によると、センサーベースのロケーショントラッキングはGPS、コンパス、そして加速度計やネットワーク、またはビーコンを通して作動します。



Wikitude AR SDK(無料体験版)のダウンロード

Geo ARを始めるための最善の方法は無料体験版をダウンロードすることです。

WIKITUDE DOWNLOAD PAGE

Wikitude Geo ARはiOSとAndroidをサポートしています。言語は、Java,JavaScript,PhoneGap,Xamarin,External LBAR Unity, Plugin,機器はFlutter,Epson,とVuzixです。

Geo ARの作成方法:サンプル・インストラクション

Wikitud SDKをダウンロードしたら、サンプル・インストラクションがどのように作成し、特定の地点にマーカーを置くのかを説明してくれます。

サンプルは4つの異なった相互に連携したセクションに分かれています。シリーズの最後で、タイトル、説明、スムースにあるものから別のものへの移動を図示する選択した予備の注意書きを書いた、完璧な、再使用可能なマーカーを得ます。

Geo AR (Point of Interest)

POIの例はどのように特定の地点のマーカーを作成できるのかが示されています。

ロケーションでのPOI

最初の章は地点の画像を表示します。そのために、現在位置を得るために呼び出す、AR.context.onLocationChanged() を使用します。位置が得られたら、それを AR.ImageDrawable に置きます。

 

すべてのJavaScriptコードはpoiatlocation.js.ファイルの中で見つけることができます。

 

すでにImage Recognition の例は、ARを表示する中で、どのようにイメージ(画像)が配置され、表示されるかが説明されています。このサンプルは、World variableが決定された時にAR.ImageResource をロードします。それは、後に私達が作成しようとした時に、それぞれのマーカーのために再利用されます。

 

poiatlocation.jsの最後のラインは独自のAR.context.onLocationChanged callbackをどのようにセットするのかを示しています。

AR.context.onLocationChanged = World.onLocationChanged;
view source code on GitHub

独自の機能World.onLocationChanged 機能がすでに呼びだされているか否かをフラグ World.initiallyLoadedDataでチェックします。また、AR.context.onLocationChangedゼロにセットする可能性があります。この場合、機能はそれ以上呼び出せず、それ以降のロケーションのアップデートは受け付けられません。

 

World.onLocationChanged の最初のcallで、Geo 情報を維持するObject(対象物)が生成されます。それは後にWorld.loadPoisFromJsonData機能で使うマーカーを生成するのに使われます。

locationChanged: function locationChangedFn(lat, lon, alt, acc) {
    // request data if not already present
    if (!World.initiallyLoadedData) {
        var poiData = {
            "id": 1,
            "longitude": (lon + (Math.random() / 5 - 0.1)),
            "latitude": (lat + (Math.random() / 5 - 0.1)),
            "altitude": 100.0
        };
        World.loadPoisFromJsonData(poiData);
        World.initiallyLoadedData = true;
    }
}
view source code on GitHub

loadPoisFromJsonData 機能は後にImage(画像)として使われる AR.ImageResourceを生成します。

// start loading marker assets
World.markerDrawable_idle = new AR.ImageResource("assets/marker_idle.png");
view source code on GitHub

マーカーを生成するために、新しい対象物(Object)AR.GeoObject が特定の地点に生成されます。AR.GeoObject複数の AR.Drawablesで一つかそれ以上のAR.GeoLocations接続します。

AR.Drawablesは複数のターゲットを定義することができます。ターゲットはカメラ、レーダー、または方向指示器で指示されます。レーダーと方向指示器の両方は後のサンプルでより細部までカバーしています。

// create the marker
var markerLocation = new AR.GeoLocation(poiData.latitude, poiData.longitude, poiData.altitude);
var markerImageDrawable_idle = new AR.ImageDrawable(markerDrawable_idle, 2.5, {
    zOrder: 0,
    opacity: 1.0
});

// create GeoObject
var markerObject = new AR.GeoObject(markerLocation, {
    drawables: {
        cam: [markerImageDrawable_idle]
    }
});
view source code on GitHub

最終的にユーザーフィードバックとしてステータスメッセージがアップデートされます。それで全てがきちんとロードされたことを示します。

World.updateStatusMessage('1 place loaded');
view source code on GitHub

POI with Label

2番目の章はマーカーオブジェクトにタイトルと説明ラベルを加えます。そしてもっと引き付ける関係するオプションで覆います。

すべてのJavaScriptの変更はpoiwithlabel.jsです。

ファイルだけが名前が変更されますがコンテンツはpoiatlocation.jsとほとんど同じだということに留意してください。

 locationChanged 機能が記述とタイトルをマーカーに加えます。

var poiData = {
    "id": 1,
    "longitude": (lon + (Math.random() / 5 - 0.1)),
    "latitude": (lat + (Math.random() / 5 - 0.1)),
    "altitude": 100.0,
    "description": "This is the description of POI#1",
    "title": "POI#1"
};
view source code on GitHub

マーカーに関する追加の変更がおきたら、Marker class (see marker.js).を分けるためにコードを抜きとることがいいやり方です。コードの部品はloadPoisFromJsonDataからMarkerclass: the creation of the AR.GeoLocation, the creation of the AR.ImageDrawable そして the creation of the AR.GeoObject.へ移動します。そうして、 loadPoisFromJsonData機能の中のMarkerのインスタンスを生成します。

// create the marker
var marker = new Marker(poiData);
view source code on GitHub

同じ場所で複数のAR.Drawablesを引き出す間、考えなければならない二つの重要な点があります。どちらを後にまたは背後に引きだすかを定義しなければなりません(Rendering order)、そして、それらはロケーションをやり直す必要があるかどうかを定義しなければなりません。この二つのシナリオのために、ARchitectは引きだしの操作を調節するいくつかの機能を持っています。

 

背景の前面にAR.Labelの位置を決めるため、引き出し可能な背景(AR.ImageDrawable2D) zOrder of 0を受け取ります。両方のラベルはzOrder of 1を持ちます。このやり方で、ラベルが引き出し可能な背景の前面に引き出されることを保証します。

確認された両方のラベルは、重なり合った同じAR.GeoObject で接続された、同じ位置の上に引き出されます。それらの位置の調整は、 AR.DrawableObjectが持っている translate.xtranslate.yを変更します。移行のための単位はSDUs(Size and Distances)で決めます。詳細はSDUsの章をご覧ください。

 

次に両方のAR.Labelsはイニシャライズと位置決めがされます。AR.ImageDrawable.と同じ要領でAR.GeoObjectのcamプロパティに追加されます。

  function Marker(poiData) {

    this.poiData = poiData;

    var markerLocation = new AR.GeoLocation(poiData.latitude, poiData.longitude, poiData.altitude);
    this.markerDrawable_idle = new AR.ImageDrawable(World.markerDrawable_idle, 2.5, {
        zOrder: 0,
        opacity: 1.0
    });

    this.titleLabel = new AR.Label(poiData.title.trunc(10), 1, {
        zOrder: 1,
        translate: {
            y: 0.55
        },
        style: {
            textColor: '#FFFFFF',
            fontStyle: AR.CONST.FONT_STYLE.BOLD
        }
    });
this.descriptionLabel = new AR.Label(poiData.description.trunc(15), 0.8, { zOrder: 1, translate: { y: -0.55 }, style: { textColor: '#FFFFFF' } }); // Changed: this.markerObject = new AR.GeoObject(markerLocation, { drawables: { cam: [this.markerDrawable_idle, this.titleLabel, this.descriptionLabel] } }); return this; }
view source code on GitHub

追加として、与えられた長さより長い文章を切り捨てる機能を延長します。この機能は短くなりすぎるタイトルや文章に使われます。

String.prototype.trunc = function(n) {
       return this.substr(0, n - 1) + (this.length > n ? '...' : '');
};
view source code on GitHub

Multiple POIs

 3番目の事例は2つの部分から成り立っています。最初の章はいかにして複数のマーカーを生成するかということで、2番目の章はマーカー選択の準備を記述しています。

複数のマーカーを生成するために、class World.を変更します。異なったPOIデータを生成するために使われるパラメーターとしての位置情報(緯度、経度)がついたrequestDataFromLocal機能をユーザーの近くのランダムなロケーションへ追加します。新機能は今までの事例で使ったloadPoisFromJsonData を呼び出す代わりにlocationChanged から呼び出されます。

World.requestDataFromLocal(lat, lon);
view source code on GitHub

POIデータが生成された後は、loadPoisFromJsonData機能は新機能 requestDataFromLocal の中から呼び出されます。

// request POI data
requestDataFromLocal: function requestDataFromLocalFn(centerPointLatitude, centerPointLongitude) {
    var poisToCreate = 20;
    var poiData = [];

    for (var i = 0; i < poisToCreate; i++) {
        poiData.push({
            "id": (i + 1),
            "longitude": (centerPointLongitude + (Math.random() / 5 - 0.1)),
            "latitude": (centerPointLatitude + (Math.random() / 5 - 0.1)),
            "description": ("This is the description of POI#" + (i + 1)),
            "altitude": "100.0",
            "name": ("POI#" + (i + 1))
        });
    }
    World.loadPoisFromJsonData(poiData);
}
view source code on GitHub

loadPoisFromJsonData の拡張現実を、何かの適合性を必要とする前に単独のObject (対象物)ではなく並列として使ったので、loadPoisFromJsonData機能の中で拡張現実として配布される並列POI情報は、poiData objectsを生成するために使われます。すべてのpoi情報Objectsの中をループを繰り返し、それぞれのObjectは新ObjectsinglePoiを生成します。 複数のマーカーを生成するために、new Marker(poiData) は、poiData Objectの中で定義されたように、違う場所、タイトル、そして文章で何度も呼び出すことができます。そうして、Marker Objedtsを生成し、それらを並列のmarkerList蓄積します。それはWorld classの中に変更可能なメンバーとして定義されます。markerList arrayは、マーカーの選択/選択解除のために必要です。そして、後でこの事例の中に記述されています。最終的にステイタス・メッセージはPOIがロードされた番号で更新されます。

// called to inject new POI data
loadPoisFromJsonData: function loadPoisFromJsonDataFn(poiData) {

    // empty list of visible markers
    World.markerList = [];

    // start loading marker assets
    World.markerDrawable_idle = new AR.ImageResource("assets/marker_idle.png");

    // loop through POI-information and create an AR.GeoObject (=Marker) per POI
    for (var currentPlaceNr = 0; currentPlaceNr < poiData.length; currentPlaceNr++) {
        var singlePoi = {
            "id": poiData[currentPlaceNr].id,
            "latitude": parseFloat(poiData[currentPlaceNr].latitude),
            "longitude": parseFloat(poiData[currentPlaceNr].longitude),
            "altitude": parseFloat(poiData[currentPlaceNr].altitude),
            "title": poiData[currentPlaceNr].name,
            "description": poiData[currentPlaceNr].description
        };

        World.markerList.push(new Marker(singlePoi));
    }

    World.updateStatusMessage(currentPlaceNr + ' places loaded');
}
view source code on GitHub

ここまでで、複数のマーカーを表示する準備は終わりました。それでは、選択されたマーカーの背景画像が、どの様に変わったかを見てみましょう。そして、別の選択した状態を操作してみましょう。

 

2番目のAR.ImageDrawablemarker.js.の中に定義されています。

 

ユーザーの反応に対応するために、onClickプロパティがそれぞれのAR.Drawable 用にセット可能です。プロパティは毎回ユーザーがdrawableの上でタップする時に呼び出される機能です。以下の断片は修正された AR.ImageDrawable 生成を示しています。

this.markerDrawable_idle = new AR.ImageDrawable(World.markerDrawable_idle, 2.5, {
    zOrder: 0,
    opacity: 1.0,
    onClick: Marker.prototype.getOnClickTrigger(this)
});
view source code on GitHub

それぞれのタップを呼び出す機能は、marker.js.の中で定義されている次のヘルプ機能から呼び戻されます。この機能は、変更可能なisSelectedのヘルプを持った選択した状況をチェックする機能です。そして適切な機能を実行します。クリックされたマーカーは拡張現実として受け渡されます。

Marker.prototype.getOnClickTrigger = function(marker) {

    return function() {
            if (marker.isSelected) {
                Marker.prototype.setDeselected(marker);

            } else {
                Marker.prototype.setSelected(marker);
                try {
                    World.onMarkerSelected(marker);
                } catch (err) {
                    alert(err);
                }
            }
    };
};
view source code on GitHub

setSelectedsetDeselected機能はMarker 機能のプロトタイプです。

 

両方の機能は同じ段取りで、しかし真逆に稼働します、これゆえに、唯一の機能 (setSelectedが詳細をカバーしています。マーカーを選ぶには3つのステップが必要です。最初は、状況が適切にセットされることです。2番目は引き出される背景が可能であること、そして標準の背景は不可能であること。これは可視される状況の1.0と可視されない0.0のあいまいなプロパティをセットすることで成されます。3番目は、選択されたマーカーの引き出し可能な背景のためにだけセットされるonClick  機能です。

Marker.prototype.setSelected = function(marker) {

    marker.isSelected = true;

    marker.markerDrawable_idle.opacity = 0.0;
    marker.markerDrawable_selected.opacity = 1.0;
    marker.markerDrawable_idle.onClick = null;
    marker.markerDrawable_selected.onClick = Marker.prototype.getOnClickTrigger(marker);
};
view source code on GitHub

ユーザーが空のスクリーンをタップした時、マーカーの選択を解除することができるようにするために、World Objectは、それぞれのマーカーを保持している並列Objectsをつかみます。

World.markerList.push(new Marker(singlePoi));
view source code on GitHub

引きだせないとなったクリックの場所を見つけるために、AR.context.に独自の機能をセットします。onScreenClickは現在選択されているマーカーが選択解除されている所です。

onScreenClick: function onScreenClickFn() {
    if (World.currentMarker) {
        World.currentMarker.setDeselected(World.currentMarker);
    }
}
view source code on GitHub

Selecting POIs

最後の章はAR.PropertyAnimations AR.AnimationGroups.の背後にあるコンセプトを記述します。それは、また、如何に方向指示器がその時点では視野の中に入っていない選択したObjectを可視化するために使われるのか、を説明します。

 

AR.PropertyAnimationsによって、ほとんどどんなARchitect Objects のプロパティもアニメーション化することができます。このサンプルは両方の引き出し可能な背景を不透明なアニメーションにします。それにより片方は消え、片方は現れています。大きさも同じくアニメーション化されます。マーカーのサイズは時間切れで変更になります、そのためラベルは引き出し可能な背景に比較して比率を保つようにアニメーション化される必要があります。AR.AnimationGroupsは同時にまたは順番にすべてのアニメーションを同期するために使われます。

 

marker.jsの中で、2つの新しい変数が宣言されます。それらはアニメーションのスタートまたはストップのどちらかに使われる AR.AnimationGroupへのリファレンスを持っています。

this.animationGroup_idle = null;
this.animationGroup_selected = null;
view source code on GitHub

marker.jsの中の機能setSelected setDeselectedは直されなければなりません。再度、setSelectedの中の変更だけを説明します。

 

 AR.AnimationGroups.には2つのタイプがあります。並列のアニメーションは同時に動きます。順番に沿ったアニメーションはいつが終わって次が動きます。このサンプルは並列のAR.AnimationGroup.を使います。

if (marker.animationGroup_selected === null) {

    var hideIdleDrawableAnimation = new AR.PropertyAnimation(marker.markerDrawable_idle, "opacity", null, 0.0, kMarker_AnimationDuration_ChangeDrawable);
    var showSelectedDrawableAnimation = new AR.PropertyAnimation(marker.markerDrawable_selected, "opacity", null, 0.8, kMarker_AnimationDuration_ChangeDrawable);

    var idleDrawableResizeAnimationX = new AR.PropertyAnimation(marker.markerDrawable_idle, 'scale.x', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));
    var selectedDrawableResizeAnimationX = new AR.PropertyAnimation(marker.markerDrawable_selected, 'scale.x', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));

    var titleLabelResizeAnimationX = new AR.PropertyAnimation(marker.titleLabel, 'scale.x', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));
    var descriptionLabelResizeAnimationX = new AR.PropertyAnimation(marker.descriptionLabel, 'scale.x', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));

    var idleDrawableResizeAnimationY = new AR.PropertyAnimation(marker.markerDrawable_idle, 'scale.y', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));
    var selectedDrawableResizeAnimationY = new AR.PropertyAnimation(marker.markerDrawable_selected, 'scale.y', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));

    var titleLabelResizeAnimationY = new AR.PropertyAnimation(marker.titleLabel, 'scale.y', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));
    var descriptionLabelResizeAnimationY = new AR.PropertyAnimation(marker.descriptionLabel, 'scale.y', null, 1.2, kMarker_AnimationDuration_Resize, new AR.EasingCurve(AR.CONST.EASING_CURVE_TYPE.EASE_OUT_ELASTIC, {
        amplitude: 2.0
    }));

    marker.animationGroup_selected = new AR.AnimationGroup(AR.CONST.ANIMATION_GROUP_TYPE.PARALLEL, [hideIdleDrawableAnimation, showSelectedDrawableAnimation, idleDrawableResizeAnimationX, selectedDrawableResizeAnimationX, titleLabelResizeAnimationX, descriptionLabelResizeAnimationX,idleDrawableResizeAnimationY, selectedDrawableResizeAnimationY, titleLabelResizeAnimationY, descriptionLabelResizeAnimationY]);
}
view source code on GitHub

スタート機能を使って AR.AnimationGroup を搭載します。

marker.animationGroup_selected.start();
view source code on GitHub

 Marker.prototype.getOnClickTrigger機能の中で、選択機能は、アニメーション無しが稼働している時にだけ、呼び出されます。

if (!Marker.prototype.isAnyAnimationRunning(marker)) {
    if (marker.isSelected) {
        Marker.prototype.setDeselected(marker);
    } else {
        Marker.prototype.setSelected(marker);
        try {
            World.onMarkerSelected(marker);
        } catch (err) {
            alert(err);
        }
    }
} else {
    AR.logger.debug('a animation is already running');
}
view source code on GitHub

方向指示器のために表示される必要がある画像を参照するAR.ImageResourceを生成します。そうしてAR.ImageResource.を使用してAR.ImageDrawable を生成します。画像の移動と停止のためのオプションをセットします。そうすると、それが画面の端に正しく表示されます。

this.directionIndicatorDrawable = new AR.ImageDrawable(World.markerDrawable_directionIndicator, 0.5, {
    enabled: false
});
view source code on GitHub

最後の段階はマーカーAR.GeoObjectの上で、指示器またはターゲットとして、AR.ImageDrawableを定義することです。方向指示器は必要がある時に自動的に表示されます。AR.Drawable のサブクラス (e.g. AR.Circle)は方向指示器として使われます。

this.markerObject = new AR.GeoObject(markerLocation, {
    drawables: {
        cam: [    this.markerDrawable_idle, 
                this.markerDrawable_selected, 
                this.titleLabel, 
                this.descriptionLabel
              ],
        indicator: this.directionIndicatorDrawable
    }
});
view source code on GitHub

Retrieving POI Data

ARchitect WorldにおけるPOIデジタル情報でリクエストと作業をするにはいくつかの方法があります。あなたのアプリケーションと事例によって、一つがもっともよくフィットするでしょう。

From Application Model

格納されているデータをロードしている横で、データベースからデータをロードすることもまた可能です。または、それをネイティブモードで生成することも可能です。あなたのデータのJSON Objectを生成するためには、プラットフォームの通常のやり方を使い、そして、それらをARchitect World's JavaScriptに渡すためにarchitectView.callJavaScript()を使います。

 

どのようにデータがJavaScriptに注入されるのかをよりよく理解するためにSampleCamContentFromNativeActivity.java を見ます。

From a Local Resource

ARchitect Worldのあなたのデータが静的である場合、コンテンツはアプリケーションの中に蓄えられなければなりません。そこでは広くアクセスできる変数が定義されるJavaScriptファイル(e.g. myjsondata.js)を生成します。

var myJsonData = …[YOUR-JSON-DATA]
view source code on GitHub

あなたのJaveScriptのどこでも可能なところにPOI情報を作るために<script src="js/myjsondata.js"/> を加えることによってARchitect Worlds HTMLの中にJavaScriptを含めます。

// request POI data
requestDataFromLocal: function requestDataFromLocalFn(lat, lon) {
    World.loadPoisFromJsonData(myJsonData);
}
view source code on GitHub

注記:このサンプルは静的なPOIデータを使い、Helper.bringPlacesToUser,を使った緯度、経度変数を書き替えています。これを削除するためにはこの行を移動させなければなりません。

From a Webservice

JQueryはデータをリモートの発生元から取りだす数々のツールを提供します。POI情報のためには、JSONフォーマットを使うことを特に推奨します。要求と構文解析はわずかな行のコードで成されます。

 

ロケーションのアップデートで発動される方式を定義するためには、e.g. AR.context.onLocationChanged = World.locationChanged;を使います。このサンプルでは、POI情報は大変に早いロケーション・アップデートの後に、要求されます。

注:World.locationChanged.の中に、もうこれ以上ロケーションアップデートを受け付けないとわかった後に、AR.context.onLocationChanged = nullをセットします。

 

サーバー情報は分離してストアーすることをお勧めします。

// holds server information
var ServerInformation = {
    // sample service returning dummy POIs
    POIDATA_SERVER: "http://example.wikitude.com/GetSamplePois/",
    POIDATA_SERVER_ARG_LAT: "lat",
    POIDATA_SERVER_ARG_LON: "lon",
    POIDATA_SERVER_ARG_NR_POIS: "nrPois"
};
view source code on GitHub

サーバーが有効なJSONに戻り、それが確実に抜けたことを確認します。(例えば、POInameの中の特別な文字など)。

 

サーバーの反応はWorld.loadPoisFromJsonData(poiData)へ送られます。そこは、マーカーの生成とそのカメラの再表示が定義されます。

// location updates
locationChanged: function locationChangedFn(lat, lon, alt, acc) {

    /* Request data from server only once*/
    if (!World.alreadyRequestedData) {
        World.requestDataFromServer(lat, lon);
        World.alreadyRequestedData = true;
    }
},
view source code on GitHub
// request POI data
requestDataFromServer: function requestDataFromServerFn(lat, lon) {

    // set helper var to avoid requesting places while loading
    World.isRequestingData = true;
    World.updateStatusMessage('Requesting places from web-service');

    // server-url to JSON content provider
    var serverUrl = ServerInformation.POIDATA_SERVER + "?" + ServerInformation.POIDATA_SERVER_ARG_LAT + "=" + lat + "&" + ServerInformation.POIDATA_SERVER_ARG_LON + "=" + lon + "&" + ServerInformation.POIDATA_SERVER_ARG_NR_POIS + "=20";

    var jqxhr = $.getJSON(serverUrl, function(data) {
        World.loadPoisFromJsonData(data);
    })
        .error(function(err) {
            World.updateStatusMessage("Invalid web-service response.", true);
            World.isRequestingData = false;
        })
        .complete(function() {
            World.isRequestingData = false;
        });
}
view source code on GitHub

Browsing POIs

カメラの中に数多くのPOIを表示することは挑戦です。どのくらいの数のPOIを出すべきなのでしょうか?同じ指示のPOIをどのように扱うのでしょうか?POIを表す最大範囲は何でしょうか?そしてどのように長い文を表示するのでしょうか?以下の事例は適切にPOI ブラウザーの事例に関して聞かれた質問をカバーしています。そして5章と1つの追加セクションで成り立っています。

Presenting Details(詳細表示)

POIは通常、名前と時には極めて長い記述を持っています。あなたのコンテンツのタイプによって、あなたはその名前と切り落とされた文章のマーカーを表示します。しかし、ユーザーにそれを選択した後で更なる情報を得ることを許しています。

jQuery Mobileはモバイル機器のための魅力的なユーザーインターフェイスを作成します。それは「書込み不要でもっとできる」を次のレベルへの御題目にしています。それぞれのモバイル機器、またはOSのために独自のアプリを書く代わりに、  jQueryのモバイルフレームワークは、あなたに、すべての普及したスマートホン、タブレット、そしてデスクトッププラットフォーム(彼らのWebSiteからの引用)の上で動く、一つの高度なブランド化されたWebSiteまたはアプリケーションをデザインさせます。私達は、拡張現実の表示のUIの構築のために jQuery mobileを使うことを推奨します。

それはよく文書化されており、アプリケーション、またはあなた自身のウエブサーバー上におかれた中に組み込むことさえできます。

 

このサンプルの中で、押されたcamマーカー(タイトルと文章の青色の箱)がサンプルの記録簿の中でindex.htmlと比較した時にPOI詳細パネルがあらわれます。

<!-- panel containing POI detail information -->
<div data-role="panel" id="panel-poidetail" data-position="right" data-display="overlay" style="background-color:#F0F0F0;" data-theme="c">

<!-- header with "close" button -->
<div data-role="header" data-theme="c">
    <h1>Details</h1>
    <a href="#header" data-rel="close">Close</a>
</div>

<!-- content of POI detail page, you may also add thumbnails etc. here if you like -->
<div data-role="content">
    <!-- title -->
    <h3 id="poi-detail-title"></h3>

    <!-- description -->
    <h4 id="poi-detail-description"></h4>

    <!-- distance -->
    <h4>Distance: <a id="poi-detail-distance"></a></h4>
</div>
view source code on GitHub

マーカーを選んだ時、POI詳細divの中で現れたコンテンツはアップデートされます。同じく、パネルは右から左へアニメーションされます。

 

マーカーを選択取消するために、panelbeforecloseのイベントがpresentingPoiDetails.jsと比較して使われます。

onMarkerSelected: function onMarkerSelectedFn(marker) {

    World.currentMarker = marker;

    // update panel values
    $("#poi-detail-title").html(marker.poiData.title);
    $("#poi-detail-description").html(marker.poiData.description);

    var distanceToUserValue = (marker.distanceToUser > 999) ? ((marker.distanceToUser / 1000).toFixed(2) + " km") : (Math.round(marker.distanceToUser) + " m");

    $("#poi-detail-distance").html(distanceToUserValue);

    // show panel
    $("#panel-poidetail").panel("open", 123);

    $("#panel-poidetail").on("panelbeforeclose", function(event, ui) {
    World.currentMarker.setDeselected(World.currentMarker);
});
view source code on GitHub

POI and AR Rader

ユーザーの近くでどこの場所にARが位置しているのかのヒントを与えることを推奨します。オリエンテーションを支援する、もっとも容易な方法はレーダーです。通常小さな点で指示します。

レーダーでのAR.GeoObject の再表示はその引き出し可能なセット(AR.GeoObject構築の2番目のAR)で定義されます。一旦、drawables.radarがセットされると、Objectはまた、レーダーの上にmarker.js:を比較してAR.Circle,として現れます。

this.radarCircle = new AR.Circle(0.03, {
    horizontalAnchor: AR.CONST.HORIZONTAL_ANCHOR.CENTER,
    opacity: 0.8,
    style: {
        fillColor: "#ffffff"
    }
}); 
this.radardrawables = [];
this.radardrawables.push(this.radarCircle);
view source code on GitHub

選択した状態を表すために別の色で追加でサークルを生成するにはmarker.js:を比較します。

this.radarCircleSelected = new AR.Circle(0.05, {
       horizontalAnchor: AR.CONST.HORIZONTAL_ANCHOR.CENTER,
       opacity: 0.8,
       style: {
           fillColor: "#0066ff"
       }
   });

this.radardrawablesSelected = [];
   this.radardrawablesSelected.push(this.radarCircleSelected);

this.markerObject = new AR.GeoObject(markerLocation, {
       drawables: {
           cam: [    this.markerDrawable_idle, 
                   this.markerDrawable_selected, 
                   this.titleLabel, 
                   this.descriptionLabel ],
           indicator: this.directionIndicatorDrawable,
           radar: this.radardrawables
       }
   });
view source code on GitHub

レーダーの中で選択したマーカーをハイライトするために、機能の中の引き出し可能機能をアップデートします。


Marker.prototype.setSelectedMarker.prototype.setDeselected,marker.js:を比較します。

marker.markerObject.drawables.radar = marker.radardrawablesSelected;
[...]
marker.markerObject.drawables.radar = marker.radardrawables;
view source code on GitHub

レーダーの位置とそのサイズはDOM element.を使って定義されます。この事例の中でid radarContainerがついた div elementindex.html:を比較します。

<div class="radarContainer_left" id="radarContainer"></div>
view source code on GitHub

レーダーのサイズと位置はa css class,の中で定義されます。(poi-radar.css:参照)

/* position of POI-radar*/

.radarContainer_left {
    position:absolute;
    top:0px;
    left:0px;
    width:100px;
    height:100px;
}
view source code on GitHub

レーダーコンテナーを参照するエレメントの完全な位置を使うための助言をします。留意点:DOM エレメントが fly via jQuery上、またはresponsive design上でアップデートされたケースの場合、R.radar.notifyUpdateRadarPosition();を使います。レーダーの位置、サイズをアップデートせざるを得なく、一方で非常に早く位置、サイズが使用される時、AR.radar.notifyUpdateRadarPosition();を使用します。

 

レーダーそのものはカスタマイズできます。そして、radar.js.と比較して、JavaScript コードの中の分離されたコンポーネントとして用意しなければなりません。

var PoiRadar = {

    hide: function hideFn() {
        AR.radar.enabled = false;
    },

    show: function initFn() {

        // the div defined in the index.htm
        AR.radar.container = document.getElementById("radarContainer");

        // set the back-ground image for the radar
        AR.radar.background = new AR.ImageResource("assets/radar_bg.png");

        // set the north-indicator image for the radar 
        // (not necessary if you don't want to display a north-indicator)
        AR.radar.northIndicator.image = new AR.ImageResource("assets/radar_north.png");

        // center of north indicator and radar-points in the radar asset, 
        // usually center of radar is in the exact middle of the background, 
        // meaning 50% X and 50% Y axis --> 0.5 for centerX/centerY
        AR.radar.centerX = 0.5;
        AR.radar.centerY = 0.5;

        AR.radar.radius = 0.3;
        AR.radar.northIndicator.radius = 0.0;

        AR.radar.enabled = true;
    },

    updatePosition: function updatePositionFn() {
        if (AR.radar.enabled) {
            AR.radar.notifyUpdateRadarPosition();
        }
    },

    // you may define some custom action when user pressed radar, 
    // e.g. display distance, custom filtering etc.
    clickedRadar: function clickedRadarFn() {
        alert("Radar Clicked");
    },

    setMaxDistance: function setMaxDistanceFn(maxDistanceMeters) {
        AR.radar.maxDistance = maxDistanceMeters;
    }
};
view source code on GitHub

レーダーコンポーネントを起動するためにPoiRadar.show機能を呼び出します。もし、要求されたらaddingradar.js:と比較してクリックすることを定義するかもしれません。

// show radar & set click-listener
PoiRadar.show();
$('#radarContainer').unbind('click');
$("#radarContainer").click(PoiRadar.clickedRadar);
view source code on GitHub

Limiting Visible POIs

ユーザーは時には、ただある決まった範囲のPOIを見ることだけに興味があるかもしれません。このサンプルはタイトルバーボタンの中にユーザーが興味の範囲を変更できるための追加ボタンを用意しています。

最初にタイトルバーの中にボタンを追加します。

index.html

<!-- header of UI holding feature buttons -->
<div id ="header-status" data-role="header" data-position="fixed" data-theme="c">
    <a href="javascript: World.showRange();" data-icon="gear" data-inline="true" data-mini="true">Range</a>
    <h1></h1>
</div>
view source code on GitHub

そのあと、距離の範囲ためにパネルレイアウトを定義します。このケースではメートルでの現在の範囲と可視化されたPOIの数がパネルに表示されています。

index.html

<!-- range panel -->
<div data-role="panel" id="panel-distance" data-position="left" data-display="overlay" style="background-color:#F0F0F0;" data-theme="c">

    <!-- header with close button -->
    <div data-role="header" data-theme="c">
        <h1>Range</h1>
        <a href="#header" data-rel="close">Close</a>
    </div>

    <!-- distance information, calculated/updated in code -->
    <div data-role="content">

    <!-- Range in m/km-->
    <h4> Range: <a id="panel-distance-value"></a></h4>

    <!-- Amount of visible places -->
    <h4> Visible: <a id="panel-distance-places"></a></h4>

    <!-- default slider -->
    <input id="panel-distance-range" type="range" data-highlight="true" name="rangeSlider" min="0" max="100" value="100" data-show-value="false" step="5" data-popup-enabled="false">
    </div>
</div>
view source code on GitHub

 World.updateRangeValuesの機能はユーザーがこの変更数値を変えた場合には、いつでも実行されます。最大の距離の正しい計算と見える場所の合計の数値に加えて、AR.context.scene.cullingDistance PoiRadar.setMaxDistanceはレーダーの中のマーカーの描写とレーダーの中の引き出し機能のアップデートのためにlimitingrange.jsと比較して実行されます。

    // updates values show in "range panel"
updateRangeValues: function updateRangeValuesFn() {

    // get current slider value (0..100);
    var slider_value = $("#panel-distance-range").val();

    // max range relative to the maximum distance of all visible places
    var maxRangeMeters = Math.round(World.getMaxDistance() * (slider_value / 100));

    // range in meters including metric m/km
    var maxRangeValue = (maxRangeMeters > 999) ? ((maxRangeMeters / 1000).toFixed(2) + " km") : (Math.round(maxRangeMeters) + " m");

    // number of places within max-range
    var placesInRange = World.getNumberOfVisiblePlacesInRange(maxRangeMeters);

    // update UI labels accordingly
    $("#panel-distance-value").html(maxRangeValue);
    $("#panel-distance-places").html((placesInRange != 1) ? (placesInRange + " Places") : (placesInRange + " Place"));

    // update culling distance, so only places within given range are rendered
    AR.context.scene.cullingDistance = Math.max(maxRangeMeters, 1);

    // update radar's maxDistance so radius of radar is updated too
    PoiRadar.setMaxDistance(Math.max(maxRangeMeters, 1));
},

// returns number of places with same or lower distance than given range
getNumberOfVisiblePlacesInRange: function getNumberOfVisiblePlacesInRangeFn(maxRangeMeters) {

    // sort markers by distance
    World.markerList.sort(World.sortByDistanceSorting);

    // loop through list and stop once a placemark is out of range ( -> very basic implementation )
    for (var i = 0; i < World.markerList.length; i++) {
        if (World.markerList[i].distanceToUser > maxRangeMeters) {
            return i;
        }
    };

    // in case no placemark is out of range -> all are visible
    return World.markerList.length;
},
view source code on GitHub

レーダーコンポーネントの位置は別のCSS スタイル(例えば、removeClassaddClass of jQuery)を使い、PoiRadar.updatePosition()を呼び出すことでアップデートできます。このサンプルでは、距離パネルが limitingrange.jsを比較した時にレーダーエレメントが右に動いています。

handlePanelMovements: function handlePanelMovementsFn() {

    $("#panel-distance").on("panelclose", function(event, ui) {
        $("#radarContainer").addClass("radarContainer_left");
        $("#radarContainer").removeClass("radarContainer_right");
        PoiRadar.updatePosition();
    });

    $("#panel-distance").on("panelopen", function(event, ui) {
        $("#radarContainer").removeClass("radarContainer_left");
        $("#radarContainer").addClass("radarContainer_right");
        PoiRadar.updatePosition();
    });
},
view source code on GitHub

ユーザーが範囲ボタンを押した時、World.showRange 機能が実行されます。

// display range slider
showRange: function showRangeFn() {
    if (World.markerList.length > 0) {

        // update labels on every range movement
        $('#panel-distance-range').change(function() {
            World.updateRangeValues();
        });

        World.updateRangeValues();
        World.handlePanelMovements();

        // open panel
        $("#panel-distance").trigger("updatelayout");
        $("#panel-distance").panel("open", 1234);
    } else {

        // no places are visible, because the are not loaded yet
        World.updateStatusMessage('No places available yet', true);
    }
}
view source code on GitHub

Reloading POI Data

ユーザーの動き、または色々な理由により手動で、POI情報を再ロードする必要があるかもしれません。この例では、POIはユーザーがリフレッシュボタンを押した時に再ロードされます。ボタンはindex.htmlの中に定義されています。そして、クリックでWorld.reloadPlaces()を呼び出します。

<a href="javascript: World.reloadPlaces()" data-icon="refresh" >Reload</a>
view source code on GitHub

World.reloadPlaces()の準備はARchitect World(reloadingPois.js)の一部で、そして、ウエブサービスからユーザーの現在のロケーションによるデータを再取得するWorld.requestDataFromServerを実行します。

 

参考:確実な状況で、あなたのウエブサービスが稼働しない、または他の接続問題が発生します。接続問題についてユーザーに通知するために、ステータスメッセージがアップデートされます。あなた自身の準備の中で、あなたはinfo popup similar.を使うことができます。

var World = {

    […]

    // reload places from content source
    reloadPlaces: function reloadPlacesFn() {
        if (!World.isRequestingData) {
            if (World.userLocation) {
                World.requestDataFromServer(World.userLocation.latitude,
                                            World.userLocation.longitude);
            } else {
                World.updateStatusMessage('Unknown user-location.', true);
            }
        } else {
            World.updateStatusMessage('Already requesting places...', true);
        }
    }

    […]
}
view source code on GitHub

Displaying Native Detail Screen

PIOの詳細をあなたの独自のスタイルで表示するのは良いと思います。このサンプルでは、ユーザーがHTMLでの'More' ボタンを押した時に大変にシンプルな独自のスクリーンを開きます。これはJavaScriptとnativeコードの間で相互に作用するデモをします。

皿にボタンがindex.htmlに追加されます。それはWorld.onPoiDetailMoreButtonClicked機能を呼び出します。

<!-- more button-->
<a href="javascript: World.onPoiDetailMoreButtonClicked();" data-role="button" data-icon="arrow-r" data-iconpos="right" data-inline="true">
    More
</a>
view source code on GitHub

World.onPoiDetailMoreButtonClicked inativedetailscreen.jsの中に準備されます。そしてAR.platform.sendJSONObject(...).を実行します。独自のプロジェクトはこのコールに割り込みます。これは以下に示します。

var World = {
    […]

    // user clicked "More" button in POI-detail panel -> fire event to open native screen
    onPoiDetailMoreButtonClicked: function onPoiDetailMoreButtonClickedFn() {

        var currentMarker = World.currentMarker;
        var markerSelectedJSON = {
            name: "markerselected",
            id: currentMarker.poiData.id,
            title: currentMarker.poiData.title,
            description: currentMarker.poiData.description
        };
        AR.platform.sendJSONObject(markerSelectedJSON);
    }

    […]
}
view source code on GitHub

独自URL案ネイティブパートを記述するこのセクションthisを見てください。

 

 ArchitectJavaScriptInterfaceListenerインターフェイスはJavaScript native codeとの間の情報を交換することを許可します。それはnative codeJavaScriptからどこに コミュニケ―トしたいのか準備してあることが必要です。

 

 onJSONObjectReceived(JSONObject jsonObject)の方式は AR.platform.sendJSONObjectinvoked. A valid JavaScriptである時であればいつでも呼び出されます。

事例

    public void onJSONObjectReceived(JSONObject jsonObject) {
        try {
            switch (jsonObject.getString("name")) {
                case "markerselected":
                    final Intent poiDetailIntent = new Intent(SampleCamActivity.this, SamplePoiDetailActivity.class);
                    poiDetailIntent.putExtra(SamplePoiDetailActivity.EXTRAS_KEY_POI_ID, jsonObject.getString("id"));
                    poiDetailIntent.putExtra(SamplePoiDetailActivity.EXTRAS_KEY_POI_TITILE, jsonObject.getString("title"));
                    poiDetailIntent.putExtra(SamplePoiDetailActivity.EXTRAS_KEY_POI_DESCR, jsonObject.getString("description"));
                    SampleCamActivity.this.startActivity(poiDetailIntent);
                    break;
            }
        } catch (JSONException e) {
            Log.e(TAG, "onJSONObjectReceived: ", e);
        }
    }

 

JavaScript の部分のさらに詳細が必要ならpresentingdetails.jsファイルを参照してください。

Capture Screen Bonus

このサンプルは友達とスナップショットをシェアーするためのcaptureScreen機能をどのよう使うのかを示します。JavaScriptnative codeの間の相互作用のコンセプトはPOIデジタルパージのサンプルと同じですが、urlListenerは今回は代わりに画像シェアーを扱います。 "Snapshot"ボタンはタイトルバーの右上です。一旦現在のスクリーンをクリックすると捉えて、ユーザーにそれをシェアーすることを促します。

 <!-- header of UI holding feature buttons -->
        <div id ="header-status" data-role="header" data-position="fixed" data-theme="c">
            <a href="javascript: World.showRange();" data-icon="gear" data-inline="true" data-mini="true">Range</a>
            <a href="javascript: World.captureScreen()" data-icon="refresh" >Snapshot</a>
            <h1></h1>
        </div>
view source code on GitHub

画像のシェアーは独自のコードで行われます。

    // tell native (urlListener) that user pressed 'Snapshot' button
    captureScreen: function captureScreenFn() {
        AR.platform.sendJSONObject({
            name: "button",
            action: "captureScreen"
        });
    },
view source code on GitHub

Solar System(Geo)

 Solar System (IR) demoとよく似て、このデモは我々のsolar sytemの惑星を表示します。しかし、それらはロケーションベースのアプローチを使い、ユーザーの近くに位置します。

それぞれの惑星の詳細情報は、init()機能の中で定義されます。ファクターは、惑星を適切なサイズの大きさに定義し、そしてすべての惑星はplanetsInfo アレイの中に結合されています。

/* put sun, planets (and pluto) in an array */
    this.planetsInfo = [sun, mercury, venus, earth, mars, jupiter, saturn, uranus, neptun, pluto];
view source code on GitHub

惑星は AR.GeoObjectによって表示されます。それは引き出し可能なように指定された惑星の画像と名前を特集しています。それぞれの惑星のAR.GeoObject は、惑星のObjectがユーザーのロケーションに相対するようにするAR.RelativeLocationを使って配置されます。それ故に、それはソーラーシステムを、ユーザーの現在位置の実際の緯度、経度に関係なしに、北を指して配置することを可能にします。

 

指示指標は太陽のAR.GeoObject に追加されます。そのため、ユーザーは、継続して正しい指示で案内されます。

 

惑星のアニメーションは3D Model sample と同様に動きます。そこでは回転の動きは、 AR.AnimationGroupを使って結合されている複数の AR.PropertyAnimationで作成されます。animate(planet)の機能は、動く惑星のためにそれらのアニメーションを生成するために作動します。

 

再度念を押すと、onClickのトリガーとされるplanetClicked()機能の3D Model sampleに類似して、HUDの上に惑星の情報は表示されます。


Combine Image Recognition and POIs(画像認識とPOIの組み合わせ)

Wikitude SDKはロケーションARベースの風景と実風景を組み合わせてユーザーにシームレスな体験を創造します。この説明はこれをどのように成し遂げるのかを示し、追加の助言をします。

 

仮想のお店のロゴを認識するためにAR.ImageTrackerを生成することから始めましょう。そして、それをAR.ImageTrackableに設置しましょう。

// Create the tracker to recognize a store logo
var trackerDataSetPath = "assets/ShopLogo.wtc";
IrAndGeo.resource = new AR.TargetCollectionResource(trackerDataSetPath)
IrAndGeo.tracker = new AR.ImageTracker(IrAndGeo.resource, {
    onTargetsLoaded: IrAndGeo.loadingStepDone,
    onError: IrAndGeo.errorLoading
});

// Create drawables to display on the recognized image
var logo = new AR.ImageDrawable(IrAndGeo.res.logo, 1.0, {
    zOrder: -1
});

// ...

IrAndGeo.menuDrawables = [logo, buttonDeal, buttonWeb, buttonStores];
IrAndGeo.dealDrawable = new AR.ImageDrawable(IrAndGeo.res.deal, 1.0, {
    enabled: false,
    onClick: IrAndGeo.hideDeal
});

// Create the object by defining the tracker, target name and its drawables
var imageTrackable = new AR.ImageTrackable(IrAndGeo.tracker, "ShopLogo", {
    drawables: {
        cam: [logo, buttonDeal, buttonWeb, buttonStores, IrAndGeo.dealDrawable, IrAndGeo.model]
    },
   // ...
});
view source code on GitHub

お店のロゴの表面に現れた画像の最終結果

これは、認識した画像の表面にすべての引き出し可能なObjectsを表示しています。ロケーションベースのAR部分は他のすべてのARchitect Worldに類似して完成させることができます。

IrAndGeo.createMarker = function(lat, lon, name) {
    var loc = new AR.GeoLocation(lat, lon);
    var imageDrawable = new AR.ImageDrawable(IrAndGeo.res.marker, 2, {
        scale: {
            x: 0,
            y: 0,
        },
        onClick: function() {
            alert("clicked");
        }
    });

    IrAndGeo.markerAnimations.push(new AR.PropertyAnimation(imageDrawable, 'scale.x', 0.0, 1.0, 1000, {
        type: AR.CONST.EASING_CURVE_TYPE.EASE_OUT_BOUNCE
    }));
    IrAndGeo.markerAnimations.push(new AR.PropertyAnimation(imageDrawable, 'scale.y', 0.0, 1.0, 1000, {
        type: AR.CONST.EASING_CURVE_TYPE.EASE_OUT_BOUNCE
    }));
    IrAndGeo.stores.push(new AR.GeoObject(loc, {
        drawables: {
            cam: imageDrawable
        },
        enabled: false
    }));
};
view source code on GitHub

上記の方法は受け渡された緯度と経度にマーカーを生成します。他のすべてのAR.GeoObject と同様に、可視化された表示は多くの引き出し可能なObjectから作成されます。AR.GeoObjectvalue enabled set to false で生成されます、そのため最初は可視化されていません。画像ターゲット上のエレメントがクリックされた時、生成されたGeoObjectsがそれを可視化されたセットにします。

可視化されるお店の位置

IrAndGeo.showStores = function() {
    // enable all GeoObjects
    IrAndGeo.stores.forEach(function(x, idx) {
        x.enabled = true;
    });

    // ...
};
view source code on GitHub

実際の風景とロケーションベースのARを結合するはやさしく容易です。実際の風景をベースにしたARは追加のコンピューターパワー(それとバッテリーパワー)を要求することを覚えておいてください。それゆえに、それが本当に必要ならば、あなたはAR.ImageTrackerだけを生成するべきです。もしそれがもはや必要ないのならば、それをAR.ImageTracker.destroy().を呼び出すことで破壊してください。

 

サンプルを見るために、このページ on this pageの画像を使うことができます。