javascript - 如何将 Azure Maps 与 Angular 10 结合使用?

标签 javascript angular azure azure-maps

我到处搜索有关如何使用 Angular 配置 Azure Maps 的正确文档,但没有找到任何内容。

我该怎么做?

最佳答案

由于不存在使用 Angular 配置 Azure Maps 的文档,因此本文将实现这一点。在本文结束时,您应该拥有一个带有 map 标记的 Azure Maps Angular 版本。在添加任何代码之前,请按照 Microsoft 网站中的步骤设置您的 Azure Map key :https://learn.microsoft.com/en-us/azure/azure-maps/

创建 Azure Maps 组件的第一步是创建一个新的 Angular 组件并将以下内容添加到 .html 文件中:

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

id 可用于在 .scss 文件中设置组件的样式。

接下来,我们将处理 .ts 文件。首先,让我们设置 map 。我们将为 map 和坐标添加以下类变量:

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

此输出将坐标发送到 map 的父组件:

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

现在我们将创建一个名为 InitMap() 的函数,并在其中添加以下代码片段来初始化 basemap 及其属性:

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'
  }
});

接下来,我们将在 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});
});

我们还必须在 ngOnInit() 内部调用 InitMap() 函数。

下一步是创建允许用户在 map 上放置和移动图钉的功能。此函数将删除 map 上的当前标记,设置新标记的坐标,初始化标记拖动处理程序,并设置 map 边界以跟踪新放置的图钉标记。为了处理所有这些操作,我们将添加此类变量:

markersReference: Marker[] = [];

这个函数:

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)});
}

现在我们将添加一个函数,使我们能够将 map 焦点集中到放置的图钉上:

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

最后,为了获取用户对 map 所做的更改,我们将订阅 map 主题及其标记。将这些输入与类变量一起添加:

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

接下来,将这些订阅添加到您的 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)));

并在组件关闭时取消订阅:

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

总体而言,.ts 文件中的类应类似于以下内容:

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();
    }
  }
}

现在您的 Azure Maps 组件已完成,您所要做的就是在您想要将其放入的任何 View 的 .html 中调用组件的实例,并协调所需的输入和输出:

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

父组件上的输入主题应如下所示:

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

您的 updateCooperatives() 函数将处理单击 map 时从用户输入发回的标记数据。

关于javascript - 如何将 Azure Maps 与 Angular 10 结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65757217/

相关文章:

Enter 上的 Angular(点击)事件按下发送 MouseEvent 而不是 KeyboardEvent

azure - 从 txt 文件读取并转换为托管磁盘

Angular PrimeNg-SideNav 关闭回调

c# - Azure 下载文本和上传文本 C#

python - 尝试使用 python 连接到 azure cosmos 客户端,出现 104 连接中止错误

javascript - Flask 如何处理 JSON?

javascript - jQuery 向上滑动行并在底部添加另一个

javascript - 调用服务器端从 javascript 继承的 C# Web 方法

javascript - 将浏览器位置聚焦在切换 block 上

angular - ng2-ckeditor 404(未找到)angular2