6

我找不到在 Angular 中使用 Azure Maps 的任何支持、模块或文档。Azure Maps 是否仍然太新并且还不支持 Angular?

我尝试了以下模块但没有成功:https ://www.npmjs.com/package/angular-azure-maps

我尝试按照 Microsoft 在 Azure Maps(非 Angular)文档中的说明进行操作,但没有成功。

我正在使用 Angular 5.2.9 版。

4

6 回答 6

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

于 2018-09-18T02:00:00.343 回答
6

将 Azure Maps 与 Angular 一起使用很容易。

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

然后,修改您的angular.json文件。将文件包含到stylesand scripts

"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>
于 2019-10-17T06:58:41.360 回答
3

我认为最好的方法是使用本机azure-maps-control以及来自Azure Maps Web 控制示例的演示。

使用@angular 测试:“^7.2.4”。

  1. npm install azure-maps-control

此包包括源代码的缩小版本以及 Azure Maps Web 控件的 TypeScript 定义。

  1. maps.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. maps.component.html

    <div id="mapContainer"></div>
    
于 2019-04-03T17:56:22.730 回答
2

除了@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 我天蓝色地图控制

编辑(几个小时后):

我尝试了该库但没有成功,同时 Azure Maps 团队创建了适当的文档,并希望有一个操作指南以使该工作以角度工作,我将继续使用 Leaflet 和 MapBox。

我希望它有所帮助。

于 2019-01-25T07:42:56.363 回答
1

@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 约定进行改进)。

于 2020-09-06T17:22:03.887 回答
0

这就是我如何让 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: ...
};
于 2021-03-12T15:13:06.137 回答