簡體   English   中英

如何在 Angular 中使用 Azure Maps

[英]How to use Azure Maps in Angular

我找不到在 Angular 中使用 Azure Maps 的任何支持、模塊或文檔。 Azure Maps 還是太新並且還不支持 Angular 嗎?

我嘗試了以下模塊但沒有成功: https : //www.npmjs.com/package/angular-azure-maps

我曾嘗試按照 Microsoft 在 Azure Maps(非 Angular)文檔中的說明進行操作,但沒有成功。

我正在使用 Angular 版本 5.2.9。

Azure Maps 是相當新的,我們自己還沒有機會研究 Angular(我是 Azure Maps 地圖控件的項目經理)。 社區在這里啟動了一個開源項目: https : //github.com/Acaisoft/angular-azure-maps我相信這是您在 npm 上嘗試的庫的源代碼。

我們確實計划研究如何在新的一年中讓 Azure Maps 在 Angular 中更易於使用,但可能會首先將其集成到現有的眾多 Angular 地圖庫之一中。

我建議提出功能請求,以便我們可以跟蹤此內容,其他人可以在此處對其進行投票: https ://feedback.azure.com/forums/909172-azure-maps

將 Azure Maps 與 Angular 結合使用很容易。

首先,您需要安裝 npm 包: npm i azure-maps-control --save

然后,修改您的angular.json文件。 將文件包含到stylesscripts

"styles": [
    "node_modules/azure-maps-control/dist/atlas.min.css",
    "src/styles.scss"
],
"scripts": [
    "node_modules/azure-maps-control/dist/atlas.min.js"
]

之后,在您的組件中,為您的地圖容器創建ViewChild並初始化地圖。 不要忘記在環境變量中包含一些 Azure Maps 訂閱密鑰。

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { Map, AuthenticationType } from 'azure-maps-control';
import { environment } from '@environments/environment';

@Component({
    selector: 'app-map-component',
    templateUrl: './map.component.html',
    styleUrls: [ './map.component.scss' ]
})
export class MapComponent implemens AfterViewInit {

    @ViewChild('map', { static: true })
    public mapContainer: ElementRef;

    public ngAfterViewInit(): void {
        const map = new Map(this.mapContainer.nativeElement, {
            center: [50.016, 36.13],
            zoom: 8,
            authOptions: {
                authType: AuthenticationType.subscriptionKey,
                subscriptionKey: environment.azureMapsSubscriptionKey
            }
        });
    }
}

這是你的map.component.html

<div #map></div>

我認為最好的方法是使用本機azure-maps-control 以及來自Azure Maps Web Control Samples 的演示。

用@angular 測試:“^7.2.4”。

  1. npm install azure-maps-control

此包包括源代碼的縮小版本以及 Azure Maps Web 控件的 TypeScript 定義。

  1. 地圖.component.ts

     import { Component, OnInit } from '@angular/core'; import * as atlas from 'azure-maps-control'; @Component({ selector: 'app-maps', templateUrl: './maps.component.html', styleUrls: ['./maps.component.scss'] }) export class MapsComponent implements OnInit { // Azure Active Directory Authentication Client ID // or Shared Key Authentication KEY // get it from portal.azure.com key: string = '{key}'; map: any; constructor( ) { } ngOnInit() { //Initialize a map instance. this.map = new atlas.Map('mapContainer', { authOptions: { authType: 'subscriptionKey', subscriptionKey: this.key } }); //Wait until the map resources are ready. this.map.events.add('ready', () => { //Create a HTML marker and add it to the map. this.map.markers.add(new atlas.HtmlMarker({ color: 'DodgerBlue', text: '10', position: [0, 0] })); }); } }
  2. 地圖.component.html

     <div id="mapContainer"></div>

除了@rbrundritt 的回答,我一直在嘗試 Acaisoft Azure Maps 庫,而且它充滿了錯誤,而且從那個 GitHub 存儲庫鏈接的樣本根本沒有工作......但我想我有好消息,那里是Chris Pendleton 的帖子,“Azure Maps 首席 PM 經理” ,談論 S1 定價層,我發現

...我們還將 TypeScript 定義與 Azure Maps Web SDK 源代碼的副本相結合,並將其作為 NPM 包提供,從而更輕松地與現代 Web 框架集成,並為您提供托管 Azure Maps 的選項Web SDK 與您的應用程序在本地連接以加快加載速度。 您可以找到Azure-Maps-Control或使用以下命令從命令行安裝它:

npm i azure-maps-control

編輯(幾個小時后):

我嘗試了這個庫但沒有成功,同時 Azure Maps 團隊創建了適當的文檔,並希望有一個如何在 angular 中工作的指南,我將繼續使用 Leaflet 和 MapBox。

我希望它有幫助。

@Vlad 和 @Alexey 的回答非常有幫助,但我想為任何想要使用示例庫中的代碼的人提供一個額外的示例,尤其是那些需要服務的示例。 下面是帶有服務模塊模糊搜索的一個版本,其中包含在 Angular 中使用所需的最小調整。

import { Component, ViewChild, ElementRef, AfterViewInit } from "@angular/core";
import * as atlas from 'azure-maps-control';
import * as atlasRest from 'azure-maps-rest'; // install npm azure-maps-rest

@Component({
    selector: 'map',
    templateUrl: './map.component.html',
    styles: ['#map {height: 300px; width: 1110px;}']
    //Remember to set the dimensions of the map container or layers may appear
    //offset or behind the map.
})

export class MapComponent implements AfterViewInit {
    @ViewChild('input') public input: ElementRef;
    @ViewChild('mapContainer') public mapContainer: ElementRef;
    private key: string = '<Your Azure Maps Key>';
    public map: any;
    public dataSource: any;
    public popup: any;
    public searchURL: any;

    ngAfterViewInit(): void {
        this.map = new atlas.Map(this.mapContainer.nativeElement, {
            view: 'Auto',
            authOptions: {
                authType: atlas.AuthenticationType.subscriptionKey,
                subscriptionKey: this.key
            }
        });

        //Create a pipeline using the Azure Maps subscription key.
        var pipeline = atlasRest.MapsURL.newPipeline(new atlasRest.SubscriptionKeyCredential(atlas.getSubscriptionKey()));

        //Create an instance of the SearchURL client.
        this.searchURL = new atlasRest.SearchURL(pipeline);

        //Wait until the map resources are ready.
        this.map.events.add('ready', () => {

            // Add zoom control
            this.map.controls.add(new atlas.control.ZoomControl(), {
                position: 'bottom-left'
            });

            //Create a data source and add it to the map.
            this.dataSource = new atlas.source.DataSource();
            this.map.sources.add(this.dataSource);

            //Add a layer for rendering the results as symbols.
            var resultsLayer = new atlas.layer.SymbolLayer(this.dataSource);
            this.map.layers.add(resultsLayer);

            //Create a popup but leave it closed so we can update it and display it later.
            this.popup = new atlas.Popup({
                position: [0, 0],
                pixelOffset: [0, -18]
            });

            //Add a click event to the results symbol layer.
            //Remember to bind the event to 'this' or the this.popup and this.map
            //lines of the symbolClicked function will return undefined!
            this.map.events.add('click', resultsLayer, this.symbolClicked.bind(this));
        });
    }

    public closePopup(): void {
        this.popup.close();
    }

    public search(): void {
        var query = this.input.nativeElement.value;

        //Remove any previous results from the map.
        this.dataSource.clear();

        this.searchURL.searchFuzzy(atlasRest.Aborter.timeout(10000), query, {
            radius: 100000,
            view: 'Auto'
        }).then(results => {
            //Get the results in GeoJSON format and add it to the data source.
            var data = results.geojson.getFeatures();
            this.dataSource.add(data);

            //Set the camera to the bounds of the results.
            this.map.setCamera({
                bounds: data.bbox,
                padding: 40
            });
        });
    }

    public symbolClicked(e): void {
        //Make sure the event occurred on a point feature.
        if (e.shapes && e.shapes.length > 0 && e.shapes[0].getType() === 'Point') {
            var properties = e.shapes[0].getProperties();

            //Using the properties, create HTML to fill the popup with useful information.
            var html = ['<div style="padding:10px;"><span style="font-size:14px;font-weight:bold;">'];
            var addressInTitle = false;

            if (properties.type === 'POI' && properties.poi && properties.poi.name) {
                html.push(properties.poi.name);
            } else if (properties.address && properties.address.freeformAddress) {
                html.push(properties.address.freeformAddress);
                addressInTitle = true;
            }

            html.push('</span><br/>');

            if (!addressInTitle && properties.address && properties.address.freeformAddress) {
                html.push(properties.address.freeformAddress, '<br/>');
            }

            html.push('<b>Type: </b>', properties.type, '<br/>');

            if (properties.entityType) {
                html.push('<b>Entity Type: </b>', properties.entityType, '<br/>');
            }

            if (properties.type === 'POI' && properties.poi) {
                if (properties.poi.phone) {
                    html.push('<b>Phone: </b>', properties.poi.phone, '<br/>');
                }

                if (properties.poi.url) {
                    html.push('<b>URL: </b>', properties.poi.url, '<br/>');
                }

                if (properties.poi.classifications) {
                    html.push('<b>Classifications:</b><br/>');
                    for (var i = 0; i < properties.poi.classifications.length; i++) {
                        for (var j = 0; j < properties.poi.classifications[i].names.length; j++) {
                            html.push(' - ', properties.poi.classifications[i].names[j].name, '<br/>');
                        }
                    }
                }

            }

            html.push('</div>');
            
            //Set the popup options.
            this.popup.setOptions({
                //Update the content of the popup.
                content: html.join(''),

                //Update the position of the popup with the pins coordinate.
                position: e.shapes[0].getCoordinates()
            });

            //Open the popup.
            this.popup.open(this.map);
        }
    }
}

html 將類似於:

<input type="search" #input>
<button (click)="search()">Search</button>

<div #mapContainer id="map"></div>

(注意:此示例旨在盡可能接近示例代碼以使比較更簡單,但可以使用 Angular 和 TypeScript 約定進行改進)。

這就是我讓 Azure 地圖用於衛星視圖的方式。

我在 app.module 中導入了傳單(只需導入,無需在導入數組中添加任何內容)。

import 'leaflet';

在我生成地圖的組件中,我創建了衛星圖層,如下所示:

const azureMapsUrl = `https://atlas.microsoft.com/map/imagery/png?api-version=1&style=satellite&zoom={z}&x={x}&y={y}&subscription-key=${myAzureMapsKey}`;
this.satelliteLayer = new L.TileLayer(azureMapsUrl);

然后我將圖層添加到我的傳單選項中:

this.leafletOptions = {
        zoomControl: false,
        minZoom: 6,
        layers: [this.satelliteLayer],
        zoom: 6,
        center: ...
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM