繁体   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