角度を操作しています Angular は、 Web アプリケーションを構築するための強力なツールと機能のセットを提供します。 これらの機能を HERE SDK および API と組み合わせることで、ユーザーにより魅力的な体験を提供できます。
たとえば、 HERE Maps を角度付きで統合して、角度アプリケーションのコンテキスト内で、インタラクティブな地図、ジオコード アドレス、ルートの計算などをすべて表示できます。
角度アプリケーションのコンテキスト内で簡単なインタラクティブマップを作成する方法については、次のセクションを参照してください。
作業を開始する前に HERE Developer アカウントにサインアップして、 API 資格情報 を取得します。 詳細については 、はじめに を参照してください。
Angular CLI をインストールします 新しい角度アプリケーションの開発を容易 にするには、角度アプリケーション( Angular CLI )を使用します。
コマンドプロンプトで、次のコマンドを入力して Angular CLI をインストールします。 npm install -g @angular/cli
次のコマンドを入力して、新しい角度プロジェクトを開始します。 ng new jsapi-angular && cd jsapi-angular
次の例に示すように、 Angular routing をインストールし、対応するプロンプトに応答して CSS スタイルシートを使用します。
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
結果 : jsapi-angular
新しいディレクトリが作成 src
され、 [ 角度( Angular ) ] 構成要素がサブディレクトリに存在します。 jsapi-angular
このディレクトリの構造は次のとおりです。
jsapi-angular
├── node_modules
├── package.json
├── .gitignore
├── .browserslistrc
├── .editorconfig
├── angular.json
├── karma.conf.js
├── README.md
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
├── dist
│ ├── ...
└── src
├── app
│ ├── app-routing.module.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ └── app.module.ts
├── assets
│ ├── ...
├── environments
| ├── ...
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
└── test.ts
maps-api-for-javascript
次 のコマンドを使用して、 NPM 設定にレジストリエントリを追加し、 https://repo.platform.here.com/ でホストされている NPM パッケージをインストールします。 npm config set @here:registry https://repo.platform.here.com/artifactory/api/npm/maps-api-for-javascript/
@here
次のコマンドを入力して、名前空間 からパッケージをインストールします。 npm install @here/maps-api-for-javascript
jsapi-angular
フォルダーに移動 tsconfig.json
し、適切なテキストエディターでファイルを開きます。
tsconfig.json
ファイルで、以下の設定をに追加 angularCompilerOptions
します。
"allowSyntheticDefaultImports" : true
任意 : 設定が正常に完了したことを確認するには、次の操作を実行します。
次のコマンドを入力します。
ng serve
結果 : このコマンドは、 " ホットリロード " 機能を持つ開発サーバーを起動します。
ブラウザで http://localhost:4200/ のアドレスに移動して、角度アプリケーションを開始します。
結果 : ブラウザに、 [ 角度のウェルカム ] 画面が表示 jsapi-angular is running!
され、メッセージが表示されます。
スタティックマップコンポーネントを追加します 角度アプリケーションで H.Map
、名前空間 インスタンスを含むコンポーネントを作成して、静的マップを生成します。 このコンポーネントは、対応するコンテナを使用してマップをレンダリングします。
Angular CLI で、次のコマンドを入力して jsmap コンポーネントを生成します。 ng generate component jsmap
結果 : このコマンド を使用すると、src/app
ディレクトリにjsmap
フォルダが作成されます。 このフォルダには、コンポーネントのビルドに必要なすべてのファイルが含まれています。 └── src
├── app
│ ├── jsmap
| | ├── jsmap.component.css
| | ├── jsmap.component.html
| | ├── jsmap.component.spec.ts
| | └── jsmap.component.ts
│ ├── app-routing.module.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ └── app.module.ts
...
jsapi-angular/src/app/jsmap
ディレクトリに移動 jsmap.component.ts
し、ファイルを開きます。
jsmap.component.ts
ファイルで、既定のコードを次のコードに置き換えます。
import { Component, ViewChild, ElementRef } from '@angular/core' ;
import H from '@here/maps-api-for-javascript' ;
@Component ( {
selector : 'app-jsmap' ,
templateUrl : './jsmap.component.html' ,
styleUrls : [ './jsmap.component.css' ]
} )
export class JsmapComponent {
private map? : H . Map;
@ViewChild ( 'map' ) mapDiv? : ElementRef;
ngAfterViewInit ( ) : void {
if ( ! this . map && this . mapDiv) {
const platform = new H. service. Platform ( {
apikey : '{YOUR_API_KEY}'
} ) ;
const layers = platform. createDefaultLayers ( ) ;
const map = new H. Map (
this . mapDiv. nativeElement,
( layers as any) . vector. normal. map,
{
pixelRatio : window. devicePixelRatio,
center : { lat : 0 , lng : 0 } ,
zoom : 2 ,
} ,
) ;
this . map = map;
}
}
}
このコード ngAfterViewInit
は、 HERE Maps API for Javascript ライブラリ をインポートし、フックを介してマップをインスタンス化します。
jsmap.component.html
ファイルを開き、ファイルの内容を次のコードで置き換えます。
< div #map id = " map" > </ div>
jsmap.component.css
ファイルを開き、次のスタイルを追加します。
#map {
width : 100%;
height : 300px;
}
jsapi-angular/src/app
ディレクトリで app.component.html
ファイルを開き、ファイルの内容を次のコードで置き換えます。
< app-jsmap> </ app-jsmap>
ブラウザで http://localhost:4200/ のアドレスに移動して、マップが正しくレンダリングされることを確認します。
結果 : ブラウザは、次の例のように、ズーム レベル 2 および 0 緯度 and 経度 の高さ 300 ピクセルのビューポイント で、外側のコンテナの幅の 100% を占めるスタティックマップをレンダリングします。
地図のサイズを変更します 次の図で強調表示されている領域に示されているように、事前に設定されたサイズのスタティックマップはランタイム中に変更できません。
図 1. 静的マップコンポーネント 動的なサイズ変更を追加してマップキャンバスを反応させ、ユーザーがブラウザウィンドウを展開したときなどにビューポイント サイズの変更に適応させることで、スタティックマップを改善できます。
そのため resize()
には、マップで明示的なメソッド呼び出しを使用して、コンテナの新しい次元に調整する必要があります。
この例では、 simple-element-resize-detector
を使用して、角度コンポーネント内でマップのサイズを変更する方法を示します。
Angular CLI で、作業ディレクトリを jsapi-angular
プロジェクトディレクトリに切り替えます。
次のコマンドを入力します。
npm install simple-element-resize-detector --save
npm install @types/simple-element-resize-detector --save-dev
次 の例に示すように、src/app/jsmap
ディレクトリからjsmap.component.ts
ファイルを開き、simple-element-resize-detector
ライブラリ を追加してインポートステートメントを調整します。
import { Component, ViewChild, ElementRef } from '@angular/core' ;
import H from '@here/maps-api-for-javascript' ;
import onResize from 'simple-element-resize-detector' ;
ngAfterViewInit
次 map.getViewPort().resize()
のコード スニペット に示すように、を使用してメソッドを更新します。
ngAfterViewInit ( ) : void {
if ( ! this . map && this . mapDiv) {
const platform = new H. service. Platform ( {
apikey : '{YOUR_API_KEY}'
} ) ;
const layers = platform. createDefaultLayers ( ) ;
const map = new H. Map (
this . mapDiv. nativeElement,
( layers as any) . vector. normal. map,
{
pixelRatio : window. devicePixelRatio,
center : { lat : 0 , lng : 0 } ,
zoom : 2 ,
} ,
) ;
onResize ( this . mapDiv. nativeElement, ( ) => {
map. getViewPort ( ) . resize ( ) ;
} ) ;
this . map = map;
}
}
結果 : 次の図に示すように、コンポーネントは、外側にあるブラウザウィンドウのサイズの変更に応じて動的に調整されます。
より複雑なユースケース の場合は、別のコンポーネントを使用して入力を取得し、ズーム レベル とマップの中心を変更できます。
[ 角度を定義( Angular CLI ) ] で次のコマンドを入力して、新しい構成要素を作成します。
ng generate component mapposition
jsap-angular
プロジェクトで src/app/mapposition
、ディレクトリに移動 mapposition.component.html
し、ファイルを開きます。
mapposition.component.html
ファイルの既定の内容を次のコードで置き換えます。
< div>
Zoom :
< input
( change) = "notify.emit($event)"
name= "zoom"
type= "number"
value= "2"
/ >
< / div>
< div>
Latitude :
< input
( change) = "notify.emit($event)"
name= "lat"
type= "number"
value= "0"
/ >
< / div>
< div>
Longitude :
< input
( change) = "notify.emit($event)"
name= "lng"
type= "number"
value= "0"
/ >
< / div>
注 mapposition
このコンポーネントには、ズーム、緯度 、経度 の 3 つの入力フィールドがあります。 新しいコードで change
は、各入力フィールドのイベントを親コンポーネントに再ディスパッチするイベントリスナーが導入されました。
src/app/mapposition/
ディレクトリから mapposition.component.ts
フィーチャを開き、ファイルの内容を次のコードで置き換えます。
import { Component, Output, EventEmitter } from '@angular/core' ;
@Component ( {
selector : 'app-mapposition' ,
templateUrl : './mapposition.component.html' ,
styleUrls : [ './mapposition.component.css' ]
} )
export class MappositionComponent {
@Output ( ) notify = new EventEmitter ( ) ;
}
注 コンポーネントのこの TypeScript 部分 は、@Output
デコレータとEventEmitter
クラスを使用して、ユーザー入力の変更について親コンポーネントに通知します。
src/app
ディレクトリから app.component.html
ファイルを開き、ファイルの内容を次のコードで置き換えます。
< app-jsmap
[zoom] = " zoom"
[lat] = " lat"
[lng] = " lng"
> </ app-jsmap>
< app-mapposition
(notify) = " handleInputChange($event)"
> </ app-mapposition>
注 このコードでは、親 app
コンポーネントを使用して、マップフィールドと入力フィールドの間で値を渡します。
src/app
ディレクトリから app.component.ts
ファイルを開き、ファイルの内容を次のコードで置き換えて変更ハンドラを追加します。
import { Component } from '@angular/core' ;
@Component ( {
selector : 'app-root' ,
templateUrl : './app.component.html' ,
styleUrls : [ './app.component.css' ] ,
} )
export class AppComponent {
title = 'jsapi-angular' ;
constructor ( ) {
this . zoom = 2 ;
this . lat = 0 ;
this . lng = 0 ;
}
zoom : number;
lat : number;
lng : number;
handleInputChange ( event : Event) {
const target = < HTMLInputElement> event. target;
if ( target) {
if ( target. name === 'zoom' ) {
this . zoom = parseFloat ( target. value) ;
}
if ( target. name === 'lat' ) {
this . lat = parseFloat ( target. value) ;
}
if ( target. name === 'lng' ) {
this . lng = parseFloat ( target. value) ;
}
}
}
}
結果 : 変更ハンドラ jsmap
はユーザーの入力に従って値を更新し、角度はこれらの値を構成要素に渡します。
src/app/jsmap
ディレクトリから jsmap.component.ts
ファイルを開き、次の操作を実行します。
次 の例に示すように、最初の import ステートメントを調整して、Input
およびSimpleChanges
クラスを含めます。 import { Component, ViewChild, ElementRef, Input, SimpleChanges } from '@angular/core' ;
JsmapComponent
クラス内で、既存 ngAfterViewInit
のフック定義の後に @Input
ズーム、緯度 、および経度 のデコレータを追加し、 ngOnChanges
次のコード スニペット に示すようにフック定義を追加します。
@Input ( ) public zoom = 2 ;
@Input ( ) public lat = 0 ;
@Input ( ) public lng = 0 ;
ngOnChanges ( changes : SimpleChanges) {
if ( this . map) {
if ( changes[ 'zoom' ] !== undefined ) {
this . map. setZoom ( changes[ 'zoom' ] . currentValue) ;
}
if ( changes[ 'lat' ] !== undefined ) {
this . map. setCenter ( { lat : changes[ 'lat' ] . currentValue, lng : this . lng} ) ;
}
if ( changes[ 'lng' ] !== undefined ) {
this . map. setCenter ( { lat : this . lat, lng : changes[ 'lng' ] . currentValue} ) ;
}
}
}
結果 : これで、角度アプリケーションは mapposition
、コンポーネントの助けを借りて入力を取得し、 app
コンポーネントに状態を保存して jsmap
から、マップが入力に応答するようにコンポーネントを更新できます。
次の例では、ベルリン で地図を中央に配置するように座標を設定し、ズーム レベル を増やすことによって、角度アプリケーションがどのように入力に応答するかを示します。
ドラッグとズームを有効にします ビューのドラッグ、拡大、または縮小の形式でマップ操作を有効にすることで、マップの対話性をさらに向上させます。
このような動作を実現 するには、H.Map
インスタンスにmapviewchange
リスナーを追加し、EventEmitter
の支援を受けてapp
状態を更新します。
app.component.ts
ファイルで App
、次のコードを追加して状態を更新します。
handleMapChange ( event : H . map. ChangeEvent) {
if ( event. newValue. lookAt) {
const lookAt = event. newValue. lookAt;
this . zoom = lookAt. zoom;
this . lat = lookAt. position. lat;
this . lng = lookAt. position. lng;
}
}
app.component.html
ファイルで、現在のコンテンツを次のコードで置き換えます。
< app-jsmap
[zoom] = " zoom"
[lat] = " lat"
[lng] = " lng"
(notify) = " handleMapChange($event)"
> </ app-jsmap>
< app-mapposition
[zoom] = " zoom"
[lat] = " lat"
[lng] = " lng"
(notify) = " handleInputChange($event)"
> </ app-mapposition>
jsmap.component.ts
次の操作を実行して、ファイルを更新します。
jsmap.component.ts
ファイルで、 Output
次 EventEmitter
の例に示すように、およびクラスを追加して import ステートメントを調整します。
import { Component, ViewChild, ElementRef, Input, SimpleChanges, Output, EventEmitter } from '@angular/core' ;
ngAfterViewInit
マップのインスタンス化後にインタラクティブな動作を有効にするリスナーをアタッチして、フックを更新します。
map. addEventListener ( 'mapviewchange' , ( ev : H . map. ChangeEvent) => {
this . notify. emit ( ev)
} ) ;
new H. mapevents. Behavior ( new H. mapevents. MapEvents ( map) ) ;
ngOnChanges
不要な地図更新を抑制するように、メソッドを更新します。
private timeoutHandle : any;
@Output ( ) notify = new EventEmitter ( ) ;
ngOnChanges ( changes : SimpleChanges) {
clearTimeout ( this . timeoutHandle) ;
this . timeoutHandle = setTimeout ( ( ) => {
if ( this . map) {
if ( changes[ 'zoom' ] !== undefined ) {
this . map. setZoom ( changes[ 'zoom' ] . currentValue) ;
}
if ( changes[ 'lat' ] !== undefined ) {
this . map. setCenter ( { lat : changes[ 'lat' ] . currentValue, lng : this . lng} ) ;
}
if ( changes[ 'lng' ] !== undefined ) {
this . map. setCenter ( { lat : this . lat, lng : changes[ 'lng' ] . currentValue} ) ;
}
}
} , 100 ) ;
}
mapposition.component.ts
ファイルで、地図の現在の位置を反映するように次のコマンドを更新します。
Input
次 @angular/core
の例に示すように、からデコレータをインポートします。 import { Component, Output, EventEmitter, Input } from '@angular/core' ;
次の入力パラメーターを追加する必要があります。クラスボディーに追加してください。 @Input ( ) public zoom = 2 ;
@Input ( ) public lat = 0 ;
@Input ( ) public lng = 0 ;
mapposition.component.html
ファイル内のファイルの内容を次のコードで置き換えて、テンプレート を調整します。
< div>
Zoom:
< input
(change) = " notify.emit($event)"
name = " zoom"
type = " number"
[value] = " zoom"
/>
</ div>
< div>
Latitude:
< input
(change) = " notify.emit($event)"
name = " lat"
type = " number"
[value] = " lat"
/>
</ div>
< div>
Longitude:
< input
(change) = " notify.emit($event)"
name = " lng"
type = " number"
[value] = " lng"
/>
</ div>
結果 : 結果のアプリケーションは、対話型のマップおよび入力フィールドで構成されます。 マップを操作すると、次の例に示すように、入力フィールドが自動的に更新されます。
マーカーを追加します 作成した角度アプリケーションは、ビジネス目標に適したカスタマイズまたは拡張を追加するためのテンプレート として機能する場合があります。 たとえば、地図マーカーを追加すると、地図上の関心ポイントの位置をすばやく効率的に視覚的に表すことができます。
jmaps.component.ts
ファイルで map
、次の例に示すように、マーカーを配置する領域の中心にプロパティを変更するように設定します。
const map = new H. Map (
this . mapDiv. nativeElement,
( layers as any) . vector. normal. map,
{
pixelRatio : window. devicePixelRatio,
zoom : 16 ,
center : { lat : 49.6107 , lng : 6.1314 }
} ,
) ;
次の例に示すように、マップ上でマークする各ジャンル別施設の座標を格納する変数を定義します。
const landmarks = [
{ name : 'Notre-Dame Cathedral' , lat : 49.610364 , lng : 6.129416 , } ,
{ name : 'Grand Ducal Palace' , lat : 49.611204 , lng : 6.130720 } ,
{ name : 'Casemates du Bock' , lat : 49.611847 , lng : 6.131925 } ,
{ name : 'Adolphe Bridge' , lat : 49.6083 , lng : 6.127109 }
] ;
landmarks
配列内の各ランドマークにマーカーを作成します。
landmarks. forEach ( landmark => {
const marker = new H. map. Marker ( { lat : landmark. lat, lng : landmark. lng } ) ;
marker. setData ( landmark. name) ;
map. addObject ( marker) ;
} ) ;
注 このコード スニペット addObject
は、各マーカーのデータをランドマーク名に設定し、メソッドを使用してマーカーをマップ オブジェクト に追加します。
結果 : 角度アプリケーションの地図がルクセンブルグ 都市の中心になり、次の図に示すようにマーカーが表示されます。
マーカーをカスタマイズします マーカーのカスタムアイコンを提供することで、マーカーの外観を制御できます。 この例では、ローカルに保存されたマーカーアイコンを使用して簡単に操作でき
src/app/assets
ディレクトリに、という名前の新しいフォルダ images
を作成します。
次 label
の例に示すように、 landmarks 配列の各ランドマークにというプロパティを追加します。
const landmarks = [
{ name : 'Notre-Dame Cathedral' , lat : 49.610364 , lng : 6.129416 , label : 'NDC' } ,
{ name : 'Grand Ducal Palace' , lat : 49.611204 , lng : 6.130720 , label : 'GDP' } ,
{ name : 'Casemates du Bock' , lat : 49.611847 , lng : 6.131925 , label : 'CdB' } ,
{ name : 'Adolphe Bridge' , lat : 49.6083 , lng : 6.127109 , label : 'AB' } ,
] ;
各ランドマークについて、次の命名規則に従ってカスタムアイコンを作成します。marker-< label_value> .png
をクリック src/app/assets/images
し、アイコンをディレクトリに保存します。
カスタムアイコンを使用するようにマーカー生成コードを更新します。
landmarks. forEach ( landmark => {
const icon = new H. map. Icon ( '/assets/images/marker-' + landmark. label + '.png' ,
{ size : { w : 80 , h : 80 }
} ) ;
const marker = new H. map. Marker ( { lat : landmark. lat, lng : landmark. lng } ,
{ data : landmark. name, icon : icon } ) ;
map. addObject ( marker) ;
} ) ;
結果 : 次の図に示すように、マップにカスタムマーカーが表示されます。
マーカーの詳細について は、「マーカーオブジェクト 」を参照してください。