角度を操作しています

Angular は、 Web アプリケーションを構築するための強力なツールと機能のセットを提供します。 これらの機能を HERE SDK および API と組み合わせることで、ユーザーにより魅力的な体験を提供できます。

たとえば、 HERE Maps を角度付きで統合して、角度アプリケーションのコンテキスト内で、インタラクティブな地図、ジオコード アドレス、ルートの計算などをすべて表示できます。

角度アプリケーションのコンテキスト内で簡単なインタラクティブマップを作成する方法については、次のセクションを参照してください。

作業を開始する前に

HERE Developer アカウントにサインアップして、 API 資格情報 を取得します。 詳細については 、はじめにを参照してください。

Angular CLI をインストールします

新しい角度アプリケーションの開発を容易にするには、角度アプリケーション( Angular CLI )を使用します。

  1. コマンドプロンプトで、次のコマンドを入力して Angular CLI をインストールします。
     npm install -g @angular/cli
    
  2. 次のコマンドを入力して、新しい角度プロジェクトを開始します。
     ng new jsapi-angular && cd jsapi-angular
    
  3. 次の例に示すように、 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
    
  4. 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/
    
  5. @here 次のコマンドを入力して、名前空間 からパッケージをインストールします。
     npm install @here/maps-api-for-javascript
    
  6. jsapi-angular フォルダーに移動 tsconfig.json し、適切なテキストエディターでファイルを開きます。

  7. tsconfig.json ファイルで、以下の設定をに追加 angularCompilerOptionsします。

     "allowSyntheticDefaultImports": true
    
  8. 任意 : 設定が正常に完了したことを確認するには、次の操作を実行します。

    1. 次のコマンドを入力します。

       ng serve
      

      結果: このコマンドは、 " ホットリロード " 機能を持つ開発サーバーを起動します。

    2. ブラウザで http://localhost:4200/ のアドレスに移動して、角度アプリケーションを開始します。

      結果: ブラウザに、 [ 角度のウェルカム ] 画面が表示 jsapi-angular is running! され、メッセージが表示されます。

スタティックマップコンポーネントを追加します

角度アプリケーションで H.Map 、名前空間 インスタンスを含むコンポーネントを作成して、静的マップを生成します。 このコンポーネントは、対応するコンテナを使用してマップをレンダリングします。

  1. 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
         ...
    
  2. jsapi-angular/src/app/jsmap ディレクトリに移動 jsmap.component.ts し、ファイルを開きます。

  3. 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) {
           // Instantiate a platform, default layers and a map as usual.
           const platform = new H.service.Platform({
             apikey: '{YOUR_API_KEY}'
           });
           const layers = platform.createDefaultLayers();
           const map = new H.Map(
             this.mapDiv.nativeElement,
             // Add type assertion to the layers object... 
             // ...to avoid any Type errors during compilation.
             (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 ライブラリ をインポートし、フックを介してマップをインスタンス化します。

  4. jsmap.component.html ファイルを開き、ファイルの内容を次のコードで置き換えます。

     <div #map id="map"></div>
    
  5. jsmap.component.css ファイルを開き、次のスタイルを追加します。

     #map {
       width: 100%;
       height: 300px;
     }
    
  6. jsapi-angular/src/app ディレクトリで app.component.html ファイルを開き、ファイルの内容を次のコードで置き換えます。

     <app-jsmap></app-jsmap>
    
  7. ブラウザで http://localhost:4200/ のアドレスに移動して、マップが正しくレンダリングされることを確認します。

結果: ブラウザは、次の例のように、ズーム レベル 2 および 0 緯度 and 経度 の高さ 300 ピクセルのビューポイント で、外側のコンテナの幅の 100% を占めるスタティックマップをレンダリングします。 100% の幅の静的マップコンポーネント

地図のサイズを変更します

次の図で強調表示されている領域に示されているように、事前に設定されたサイズのスタティックマップはランタイム中に変更できません。

静的マップコンポーネント
図 1. 静的マップコンポーネント

動的なサイズ変更を追加してマップキャンバスを反応させ、ユーザーがブラウザウィンドウを展開したときなどにビューポイント サイズの変更に適応させることで、スタティックマップを改善できます。

そのため resize() には、マップで明示的なメソッド呼び出しを使用して、コンテナの新しい次元に調整する必要があります。

この例では、 simple-element-resize-detector を使用して、角度コンポーネント内でマップのサイズを変更する方法を示します。

  1. Angular CLI で、作業ディレクトリを jsapi-angular プロジェクトディレクトリに切り替えます。

  2. 次のコマンドを入力します。

     npm install simple-element-resize-detector --save
     npm install @types/simple-element-resize-detector --save-dev
    
  3. 次 の例に示すように、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';
    
  4. ngAfterViewInitmap.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;
         }
       }
    

結果: 次の図に示すように、コンポーネントは、外側にあるブラウザウィンドウのサイズの変更に応じて動的に調整されます。 ダイナミックマップコンポーネント

入力パラメータに応答するようにマップを設定します

より複雑なユースケース の場合は、別のコンポーネントを使用して入力を取得し、ズーム レベル とマップの中心を変更できます。

  1. [ 角度を定義( Angular CLI ) ] で次のコマンドを入力して、新しい構成要素を作成します。

     ng generate component mapposition
    
  2. jsap-angular プロジェクトで src/app/mapposition 、ディレクトリに移動 mapposition.component.html し、ファイルを開きます。

  3. 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 は、各入力フィールドのイベントを親コンポーネントに再ディスパッチするイベントリスナーが導入されました。

  4. 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クラスを使用して、ユーザー入力の変更について親コンポーネントに通知します。

  5. src/app ディレクトリから app.component.html ファイルを開き、ファイルの内容を次のコードで置き換えます。

     <app-jsmap
       [zoom]="zoom"
       [lat]="lat"
       [lng]="lng"
     ></app-jsmap>
     <app-mapposition
       (notify)="handleInputChange($event)"
     ></app-mapposition>
    

    このコードでは、親 app コンポーネントを使用して、マップフィールドと入力フィールドの間で値を渡します。

  6. 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 はユーザーの入力に従って値を更新し、角度はこれらの値を構成要素に渡します。

  7. src/app/jsmap ディレクトリから jsmap.component.ts ファイルを開き、次の操作を実行します。

    1. 次 の例に示すように、最初の import ステートメントを調整して、InputおよびSimpleChangesクラスを含めます。
       import { Component, ViewChild, ElementRef, Input, SimpleChanges } from '@angular/core';
      
    2. 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状態を更新します。

  1. 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;
         }
       }
    
  2. 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>
    
  3. jsmap.component.ts 次の操作を実行して、ファイルを更新します。

    1. jsmap.component.ts ファイルで、 OutputEventEmitter の例に示すように、およびクラスを追加して import ステートメントを調整します。

       import { Component, ViewChild, ElementRef, Input, SimpleChanges, Output, EventEmitter } from '@angular/core';
      
    2. ngAfterViewInit マップのインスタンス化後にインタラクティブな動作を有効にするリスナーをアタッチして、フックを更新します。

       map.addEventListener('mapviewchange', (ev: H.map.ChangeEvent) => {
         this.notify.emit(ev)
       });
       new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
      
    3. 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);
         }
      
  4. mapposition.component.ts ファイルで、地図の現在の位置を反映するように次のコマンドを更新します。

    1. Input@angular/coreの例に示すように、からデコレータをインポートします。
       import { Component, Output, EventEmitter, Input } from '@angular/core';
      
    2. 次の入力パラメーターを追加する必要があります。クラスボディーに追加してください。
         @Input() public zoom = 2;
         @Input() public lat = 0;
         @Input() public lng = 0;
      
  5. 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>
    

結果: 結果のアプリケーションは、対話型のマップおよび入力フィールドで構成されます。 マップを操作すると、次の例に示すように、入力フィールドが自動的に更新されます。 Interactive Map コンポーネント

マーカーを追加します

作成した角度アプリケーションは、ビジネス目標に適したカスタマイズまたは拡張を追加するためのテンプレート として機能する場合があります。 たとえば、地図マーカーを追加すると、地図上の関心ポイントの位置をすばやく効率的に視覚的に表すことができます。

  1. jmaps.component.ts ファイルで map 、次の例に示すように、マーカーを配置する領域の中心にプロパティを変更するように設定します。

     const map = new H.Map(
       this.mapDiv.nativeElement,
       (layers as any).vector.normal.map,
       {
         pixelRatio: window.devicePixelRatio,
         // In this example, the map centers on
         // Luxembourg City, with the zoom level of 16:
         zoom: 16,
         center: { lat: 49.6107, lng: 6.1314 }
       },
     );
    
  2. 次の例に示すように、マップ上でマークする各ジャンル別施設の座標を格納する変数を定義します。

     // This array stores coordinates of some interesting landmarks in Luxembourg City:
     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}
     ];
    
  3. landmarks 配列内の各ランドマークにマーカーを作成します。

     landmarks.forEach(landmark => {
       const marker = new H.map.Marker({ lat: landmark.lat, lng: landmark.lng });
       marker.setData(landmark.name);
       map.addObject(marker);
     });
    

    このコード スニペット addObject は、各マーカーのデータをランドマーク名に設定し、メソッドを使用してマーカーをマップ オブジェクト に追加します。

結果: 角度アプリケーションの地図がルクセンブルグ 都市の中心になり、次の図に示すようにマーカーが表示されます。 マーカーを表示するマップコンポーネント

マーカーをカスタマイズします

マーカーのカスタムアイコンを提供することで、マーカーの外観を制御できます。 この例では、ローカルに保存されたマーカーアイコンを使用して簡単に操作でき

  1. src/app/assets ディレクトリに、という名前の新しいフォルダ imagesを作成します。

  2. 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'},
     ];
    
  3. 各ランドマークについて、次の命名規則に従ってカスタムアイコンを作成します。marker-<label_value>.pngをクリック src/app/assets/images し、アイコンをディレクトリに保存します。

  4. カスタムアイコンを使用するようにマーカー生成コードを更新します。

     landmarks.forEach(landmark => {
       // For each marker, select the icon based on the corresponding landmark label:
       const icon = new H.map.Icon('/assets/images/marker-' + landmark.label + '.png',
         // Adjust the marker size to your needs: 
         {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);
     });
    

結果: 次の図に示すように、マップにカスタムマーカーが表示されます。 カスタムマーカー付きのマップ オブジェクト

マーカーの詳細について は、「マーカーオブジェクト」を参照してください。

」に一致する結果は 件です

    」に一致する結果はありません