简体   繁体   English

如何使用 Azure 映射与 Angular 10? [解决了]

[英]How to Use Azure Maps with Angular 10? [SOLVED]

I've searched high and low for proper documentation on how to configure Azure Maps with Angular and haven't found anything.我已经到处搜索了有关如何使用 Angular 配置 Azure 地图的正确文档,但没有找到任何东西。 How do I do this?我该怎么做呢?

(Please look to the comments for my self-answered question) (请查看我的自我回答问题的评论)

As documentation for configuring Azure Maps with Angular does not exist, this post will accomplish that instead.由于不存在使用 Angular 配置 Azure 地图的文档,因此这篇文章将实现这一点。 By the end of this post, you should have a working Angular version of Azure Maps with map markers.在这篇文章的结尾,你应该有一个工作 Angular 版本的 Azure 地图与 map 标记。 Before adding any code, please follow the steps from the Microsoft website to set up your Azure Map keys: https://docs.microsoft.com/en-us/azure/azure-maps/在添加任何代码之前,请按照 Microsoft 网站上的步骤设置您的 Azure Map 密钥: https://docs.microsoft.com/en-us/mapazure

The first step to create your Azure Maps component is to create a new Angular component and add the following to your.html file:创建 Azure 地图组件的第一步是创建一个新的 Angular 组件并将以下内容添加到您的.html 文件中:

<div id="azure-map"></div>

The id can be used for styling your component in the.scss file. id 可用于在 .scss 文件中设置组件的样式。

Next, we will work on the.ts file.接下来,我们将处理 .ts 文件。 First, let's set up the map.首先,让我们设置 map。 We'll add the following class variables for the map and coordinates:我们将为 map 和坐标添加以下 class 变量:

map: any;
defaultLat: number = 47.608013;  // Seattle coordinates
defaultLng: number = -122.335167;

and this output to emit coordinates to the map's parent component:这个 output 向地图的父组件发出坐标:

@Output() outputCoordinates: EventEmitter<number[]> = new EventEmitter<number[]>();

Now we will make a function called InitMap() and add this code snippet inside to initialize the base map and its properties:现在我们将创建一个名为 InitMap() 的 function 并在其中添加此代码片段以初始化基础 map 及其属性:

this.map = new atlas.Map('azure-map', {
  center: [this.defaultLng, this.defaultLat],
  zoom: 12,
  language: 'en-US',
  showLogo: true,
  showFeedbackLink: false,
  dragRotateInteraction: false,
  authOptions: {
    authType: AuthenticationType.subscriptionKey,
    subscriptionKey: 'YOUR_SUBSCRIPTION_KEY_HERE'
  }
});

Next, we will add this code snippet inside InitMap() to register the map click hander and zoom controls:接下来,我们将在 InitMap() 中添加此代码片段以注册 map 单击处理程序和缩放控件:

this.map.events.add('ready', () => {
  // Register the map click handler
  this.map.events.add('click', (e) => {
    this.outputCoordinates.emit([e.position[0], e.position[1]]); // 0 = longitude, 1 = latitude
  });

  //Construct a zoom control and add it to the map.
  this.map.controls.add(new atlas.control.ZoomControl({
    style: ControlStyle.auto,
    zoomDelta: 1
  }), {position: ControlPosition.BottomLeft});
});

We must also call the InitMap() function inside of ngOnInit().我们还必须在 ngOnInit() 内部调用 InitMap() function。

The next step is to create the functionality to allow the user to drop and move pins on the map.下一步是创建允许用户在 map 上放置和移动引脚的功能。 This function will erase the current marker on the map, set the new marker's coordinates, initialize the marker drag handler, and set the boundaries of the map to track the newly placed pin marker.此 function 将擦除 map 上的当前标记,设置新标记的坐标,初始化标记拖动处理程序,并设置 map 的边界以跟踪新放置的标记。 To handle all these operations, we will add this class variable:为了处理所有这些操作,我们将添加这个 class 变量:

markersReference: Marker[] = [];

and this function:还有这个 function:

setMarkers(markers: Marker[]) {
  if (markers && markers.length > 0) {
    this.markersReference = markers;
    this.map.markers.clear();
    let boundsPositions: Array<{lng: number, lat:number}> = [];
    for (let marker of markers) {
      if (marker.latitude && marker.longitude) {
      let htmlMarker = new atlas.HtmlMarker({
        draggable: true,
        position: [marker.longitude, marker.latitude]  // longitude first
      });
      // Register the marker drag handler
      this.map.events.add('dragend', htmlMarker, (e) => {
        var pos = htmlMarker.getOptions().position;
        this.outputCoordinates.emit([pos[0], pos[1]]); // 0 = longitude, 1 = latitude
      });
      boundsPositions.push({lng: marker.longitude, lat: marker.latitude}) // lat, lng
      this.map.markers.add(htmlMarker);
    }
  }
  this.map.setCamera({padding: {top: 20, bottom: 20, left: 20, right: 20}, maxZoom: 16,
    bounds: atlas.data.BoundingBox.fromLatLngs(boundsPositions)});
}

Now we will add a function that allows us to center the map focus onto the dropped pin:现在我们将添加一个 function,它允许我们将 map 焦点集中到放置的引脚上:

centerMapWithCoords(lon: number, lat: number) {
  this.map.setCamera({zoom: 12, maxZoom: 16, center: [lon, lat]});
}

Lastly, in order to pick up changes that the user makes to the map, we will subscribe to the map subject and its markers.最后,为了了解用户对 map 所做的更改,我们将订阅 map 主题及其标记。 Add these inputs alongside your class variables:将这些输入与您的 class 变量一起添加:

@Input() markerDataSubject: Subject<Marker[]> = new Subject<Marker[]>();
@Input() centerMapSubject: Subject<{lng: number, lat: number}> = new Subject<{lng: number, lat: number}>();

Next, add these subscriptions to your ngOnInit():接下来,将这些订阅添加到您的 ngOnInit() 中:

this.subscriptions.push((this.centerMapSubject).asObservable().subscribe((coords) =>
  this.centerMapWithCoords(coords.lng, coords.lat)));
this.subscriptions.push((this.markerDataSubject).asObservable().subscribe((markers) =>
  this.setMarkers(markers)));

And unsubscribe when the component is closed:并在组件关闭时取消订阅:

ngOnDestroy() {
  for (const s of this.subscriptions) {
    s.unsubscribe();
  }
}

Overall, the class in your.ts file should look similar to the following:总体而言,您的 .ts 文件中的 class 应类似于以下内容:

export class AzureMapComponent implements OnInit {

  @Input() markerDataSubject: Subject<Marker[]> = new Subject<Marker[]>();
  @Input() centerMapSubject: Subject<{lng: number, lat: number}> = new Subject<{lng: number, lat: number}>();

  @Output() outputCoordinates: EventEmitter<number[]> = new EventEmitter<number[]>();

  subscriptions: Subscription[] = [];
  map: any;
  markersReference: Marker[] = [];
  defaultLat: number = 47.608013;  // Seattle coordinates
  defaultLng: number = -122.335167;

  ngOnInit() {
    this.InitMap();
    this.subscriptions.push((this.centerMapSubject).asObservable().subscribe((coords) =>
      this.centerMapWithCoords(coords.lng, coords.lat)));
    this.subscriptions.push((this.markerDataSubject).asObservable().subscribe((markers) =>
      this.setMarkers(markers)));
  }

  //Create an instance of the map control and set some options.
  InitMap() {
    this.map = new atlas.Map('azure-map', {
      center: [this.defaultLng, this.defaultLat],
      zoom: 12,
      language: 'en-US',
      showLogo: true,
      showFeedbackLink: false,
      dragRotateInteraction: false,
      authOptions: {
        authType: AuthenticationType.subscriptionKey,
        subscriptionKey: 'YOUR_SUBSCRIPTION_KEY_HERE'
      }
    });

    this.map.events.add('ready', () => {
      // Register the map click handler
      this.map.events.add('click', (e) => {
        this.outputCoordinates.emit([e.position[0], e.position[1]]); // 0 = longitude, 1 = latitude
      });

      //Construct a zoom control and add it to the map.
      this.map.controls.add(new atlas.control.ZoomControl({
        style: ControlStyle.auto,
        zoomDelta: 1
      }), {position: ControlPosition.BottomLeft});
    });
  }

  setMarkers(markers: Marker[]) {
    if (markers && markers.length > 0) {
      this.markersReference = markers;
      this.map.markers.clear();
      let boundsPositions: Array<{lng: number, lat:number}> = [];
      for (let marker of markers) {
        if (marker.latitude && marker.longitude) {
          let htmlMarker = new atlas.HtmlMarker({
            draggable: true,
            position: [marker.longitude, marker.latitude]  // longitude first
          });
          // Register the marker drag handler
          this.map.events.add('dragend', htmlMarker, (e) => {
            var pos = htmlMarker.getOptions().position;
            this.outputCoordinates.emit([pos[0], pos[1]]); // 0 = longitude, 1 = latitude
          });
          boundsPositions.push({lng: marker.longitude, lat: marker.latitude}) // lat, lng
          this.map.markers.add(htmlMarker);
        }
      }
      this.map.setCamera({padding: {top: 20, bottom: 20, left: 20, right: 20}, maxZoom: 16,
        bounds: atlas.data.BoundingBox.fromLatLngs(boundsPositions)});
    }
  }

  centerMapWithCoords(lon: number, lat: number) {
    this.map.setCamera({zoom: 12, maxZoom: 16, center: [lon, lat]});
  }

  ngOnDestroy() {
    for (const s of this.subscriptions) {
      s.unsubscribe();
    }
  }
}

Now that your Azure Maps component is complete, all you have to do is call an instance of your component within the.html of whatever view you'd like to place it in and coordinate the required inputs and output:现在您的 Azure 地图组件已完成,您所要做的就是在您想要放置它的任何视图的.html 中调用您的组件实例并协调所需的输入和 Z78E6221F6393D1356DZF81DB84CE:

<app-azure-map
    [markerDataSubject]="locationMarkerSubject"
    [centerMapSubject]="centerMapSubject"
    (outputCoordinates)="updateCoordinates($event)">
</app-azure-map>

The input subjects on your parent component should look something like this:父组件上的输入主题应如下所示:

locationMarkerSubject: Subject<Marker[]> = new Subject<Marker[]>();
centerMapSubject: Subject<{lng: number, lat: number}> = new Subject<{lng: number, lat: number}>();

And your updateCoordinates() function will handle the marker data sent back from user input upon clicking the map.您的 updateCoordinates() function 将在单击 map 时处理从用户输入返回的标记数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM