博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
angular id标记_使用传单在Angular中构建地图,第2部分:标记服务
阅读量:2511 次
发布时间:2019-05-11

本文共 12148 字,大约阅读时间需要 40 分钟。

angular id标记

, we set up our environment to create a basic map using and Angular. Let’s go a bit further now and add markers to our map.

一篇 ,我们设置了环境以使用和Angular创建基本地图。 现在让我们再走一点,在地图上添加标记。

Maps are great, but augmenting our maps with data is even better. Let’s discuss how we can add markers to our map in an Angular way. That is, we’ll be using a service to manage our marker logic.

地图很棒,但是用数据扩充我们的地图更好。 让我们讨论如何以Angular方式向地图添加标记。 也就是说,我们将使用服务来管理标记逻辑。

建立 (Setup)

Recall that our directory structure looked like this:

回想一下我们的目录结构如下:

leaflet-example|_ node_modules/|_ package.json\_ src/    \_ app/        |_ app.module.ts        |_ app.routing.ts        |_ app.component.ts        |_ app.component.html        |_ app.component.scss        |        |_ map/        |     |_ map.component.ts        |     |_ map.component.html        |     \_ map.component.scss        |        \_ _services/

Navigate to the _services/ directory at the CLI and generate the service that will be responsible for managing our marker data:

导航至CLI的_services/目录,并生成将负责管理标记数据的服务:

$ ng generate service marker

Add this new service as a provider in your app.module.ts. We’ll also be loading the data from our assets folder so we’ll need to include the HttpClientModule In all, our new app.module.ts should look like this:

将此新服务添加为您的app.module.ts的提供者。 我们还将从资产文件夹中加载数据,因此我们需要包括HttpClientModule 。总之,新的app.module.ts应该如下所示:

app.module.ts
app.module.ts
import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppComponent } from './app.component';import { MapComponent } from './map/map.component';import { MarkerService } from './_services/marker.service';import { HttpClientModule } from '@angular/common/http';@NgModule({  declarations: [    AppComponent,    MapComponent  ],  imports: [    BrowserModule,    HttpClientModule  ],  providers: [    MarkerService  ],  bootstrap: [AppComponent]})export class AppModule {}

The data I’ll be plotting is stored as a containing the US State capitals. I’ve also added properties to each capital including the state name, capital name, and population. We’ll be using these additional properties later, for now let’s just load the data and plot them as markers.

我将要绘制的数据存储为包含美国州首府的 。 我还向每个首都添加了属性,包括州名称,首都名称和人口。 稍后我们将使用这些附加属性,现在让我们仅加载数据并将其绘制为标记。

加载和绘制标记 (Loading and Plotting Markers)

Open up your newly minted marker.service.ts and add HttpClient to the constructor. Let’s also declare the path to the geojson file.

打开新marker.service.ts并将HttpClient添加到构造函数中。 我们还要声明geojson文件的路径。

marker.service.ts
标记服务
import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';@Injectable({  providedIn: 'root'})export class MarkerService {  capitals: string = '/assets/data/usa-capitals.geojson';  constructor(private http: HttpClient) {  }}

Create a new function that will load the geojson data and create the markers. I’ll call mine makeCapitalMarkers. This function will take in a Leaflet map as a parameter, so we have to import Leaflet into this service.

创建一个新函数,该函数将加载geojson数据并创建标记。 我将其命名为makeCapitalMarkers 。 此功能将以Leaflet映射作为参数,因此我们必须将Leaflet导入此服务。

marker.service.ts
标记服务
import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import * as L from 'leaflet';@Injectable({  providedIn: 'root'})export class MarkerService {  capitals: string = '/assets/data/usa-capitals.geojson';  constructor(private http: HttpClient) {  } makeCapitalMarkers(map: L.map): void {  }}

Using HttpClient, get the data and subscribe to the result. Once we have our data, we then loop through each feature, construct a marker, and add it to the map.

使用HttpClient ,获取数据并订阅结果。 有了数据后,我们便遍历每个要素,构造一个标记,然后将其添加到地图中。

marker.service.ts
标记服务
import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import * as L from 'leaflet';@Injectable({  providedIn: 'root'})export class MarkerService {  capitals: string = '/assets/data/usa-capitals.geojson';  constructor(private http: HttpClient) {  }  makeCapitalMarkers(map: L.map): void {    this.http.get(this.capitals).subscribe((res: any) => {      for (const c of res.features) {        const lat = c.geometry.coordinates[0];        const lon = c.geometry.coordinates[1];        const marker = L.marker([lon, lat]).addTo(map);      }    });  }}

We’ve now written the logic for loading and adding our markers to our map, so now all we have to do now is call this method from MapComponent.

现在,我们已经编写了将标记加载和添加到地图的逻辑,因此现在要做的就是从MapComponent调用此方法。

map.component.ts
map.component.ts
import { AfterViewInit, Component } from '@angular/core';import * as L from 'leaflet';import { icon, Marker } from 'leaflet';import { MarkerService } from '../_services/marker.service';@Component({  selector: 'app-map',  templateUrl: './map.component.html',  styleUrls: ['./map.component.scss']})export class MapComponent implements AfterViewInit {  private map;  constructor(private markerService: MarkerService) {  }  ngAfterViewInit(): void {    this.initMap();    this.markerService.makeCapitalMarkers(this.map);  }  private initMap(): void {    this.map = L.map('map', {      center: [39.8282, -98.5795],      zoom: 3    });    const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {      maxZoom: 19,      attribution: '© OpenStreetMap'    });    tiles.addTo(this.map);  }}


At the time of writing this, there is a known Leaflet bug causing default marker images to not display.

在撰写本文时,有一个已知的Leaflet Bug,导致默认标记图像无法显示。

When using the Angular CLI, Leaflet’s assets don’t get properly copied to our build folder causing the app to complain that markers are missing. If your markers aren’t showing up check your browser’s console for any error messages similar to this:

使用Angular CLI时,Leaflet的资产未正确复制到我们的build文件夹中,导致应用程序抱怨缺少标记。 如果您的标记未显示,请检查浏览器的控制台中是否有类似以下内容的错误消息:

marker-icon-2x.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)marker-shadow.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)

This is remedied by doing a couple things:

通过执行以下几项操作可以纠正此问题:

  • Edit our angular.json file to copy Leaflet’s assets locally

    编辑我们的angular.json文件以在本地复制Leaflet的资产

  • Set the default icon in the marker prototype

    在标记原型中设置默认图标

To do the first step, open up angular.json and add the following lines to your “assets” stanza:

要执行第一步,请打开angular.json并将以下行添加到“资产”节中:

angular.json
angular.json
"assets": [  "src/favicon.ico",  "src/assets",  {    "glob": "**/*",    "input": "node_modules/leaflet/dist/images/",    "output": "./assets"  }],

This will copy leaflet’s marker images locally.

这将在本地复制传单的标记图像。

Then, in map.component.ts add the following lines before the @Component to set the marker icon:

然后,在map.component.ts ,在@Component之前添加以下几行以设置标记图标:

map.component.ts
map.component.ts
const iconRetinaUrl = 'assets/marker-icon-2x.png';const iconUrl = 'assets/marker-icon.png';const shadowUrl = 'assets/marker-shadow.png';const iconDefault = L.icon({  iconRetinaUrl,  iconUrl,  shadowUrl,  iconSize: [25, 41],  iconAnchor: [12, 41],  popupAnchor: [1, -34],  tooltipAnchor: [16, -28],  shadowSize: [41, 41]});L.Marker.prototype.options.icon = iconDefault;


Run your app and launch to see your state capitals.

运行您的应用程序并启动来查看您的州首字母。

Success! 🏆

成功! 🏆

圆形标记 (Circle Markers)

We can now load and plot our markers. However, suppose that we want to visualize the relative sizes of the capital populations. Earlier, I mentioned that I added population data to the geojson properties, so all we have to do is leverage this property in some way when plotting the markers. Let’s do this by creating circle markers instead of the default markers.

现在,我们可以加载并绘制标记。 但是,假设我们要可视化资本人口的相对规模。 之前,我提到我将填充数据添加到geojson属性,因此我们要做的就是在绘制标记时以某种方式利用此属性。 通过创建圆形标记而不是默认标记来实现。

In our MarkerService, let’s create a different function called makeCapitalCircleMarkers() that will create circle markers instead of regular markers.

在我们的MarkerService ,我们创建另一个名为makeCapitalCircleMarkers()函数,该函数将创建圆形标记而不是常规标记。

marker.service.ts
标记服务
makeCapitalCircleMarkers(map: L.map): void {    this.http.get(this.capitals).subscribe((res: any) => {      for (const c of res.features) {        const lat = c.geometry.coordinates[0];        const lon = c.geometry.coordinates[1];        const circle = L.circleMarker([lon, lat]).addTo(map);      }    });

Call this function in MapComponent:

在MapComponent中调用此函数:

map.component.ts
map.component.ts
ngAfterViewInit(): void {    this.initMap();    // this.markerService.makeCapitalMarkers(this.map);    this.markerService.makeCapitalCircleMarkers(this.map);  }

Hey, nice circles you got there, but that doesn’t tell me anything about the population size. One thing to mention is that the circle marker styles can be set upon initialization using an optional parameters object, and one of these styles includes the circle’s radius. We’ll set the radius of each circle using this way. For example, we can set each circle’s radius to 20 using the following:

嘿,您到过的圈子不错,但这并没有告诉我有关人口数量的任何信息。 值得一提的是,圆形标记样式可以在初始化时使用可选参数对象进行设置,其中一种样式包括圆形的半径。 我们将使用这种方式设置每个圆的半径。 例如,我们可以使用以下命令将每个圆的半径设置为20:

marker.service.ts
标记服务
const circle = L.circleMarker([lon, lat],     {      radius: 20    }).addTo(map);

This sizes all radii to be the same value (20), so instead of setting the radius as a number we’ll define the radius as a function that will scale the radius based on population.

这会将所有半径的大小设置为相同的值(20),因此,我们将半径定义为一个函数,该函数将根据总体比例缩放半径,而不是将半径设置为数字。

Create that scaling function at the top of your service:

在服务顶部创建该缩放功能:

static ScaledRadius(val: number, maxVal: number): number {  return 20 * (val / maxVal);}

This function takes in a value (population), a max value (maximum population), and returns a radius in the range [0 - 20].

此函数输入一个值(人口),一个最大值(最大人口),并返回范围为[0-20]的半径。

We find the maximum population by using this slick one-liner:

我们使用这种光滑的单线查找最大人口:

const maxVal = Math.max(...res.features.map(x => x.properties.population), 0);

Finally, we put it all together by using ScaledRadius as our radius function.

最后,我们将ScaledRadius用作半径函数将它们放在一起。

Highlighting our changes, our final MarkerService now looks like this:

强调我们的更改,我们最终的MarkerService现在看起来像这样:

marker.service.ts
标记服务
import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import * as L from 'leaflet';@Injectable({  providedIn: 'root'})export class MarkerService {  capitals: string = '/assets/data/usa-capitals.geojson';  static ScaledRadius(val: number, maxVal: number): number {    return 20 * (val / maxVal);  }  constructor(private http: HttpClient) {  }  makeCapitalMarkers(map: L.map): void {    this.http.get(this.capitals).subscribe((res: any) => {      for (const c of res.features) {        const lat = c.geometry.coordinates[0];        const lon = c.geometry.coordinates[1];        const marker = L.marker([lon, lat]).addTo(map);      }    });  }  makeCapitalCircleMarkers(map: L.map): void {    this.http.get(this.capitals).subscribe((res: any) => {      // Find the maximum population to scale the radii by.      const maxVal = Math.max(...res.features.map(x => x.properties.population), 0);      for (const c of res.features) {        const lat = c.geometry.coordinates[0];        const lon = c.geometry.coordinates[1];        const circle = L.circleMarker([lon, lat], {  radius: MarkerService.ScaledRadius(c.properties.population, maxVal)}).addTo(map);      }    });  }}

Launch the app and navigate to to reveal our new scaled circle markers.

启动应用程序并导航到以显示我们新的缩放圆圈标记。

And this is the moment you realize that the most populous state capital is Phoenix, Arizona. Who knew?

这是您意识到人口最多的州首府是亚利桑那州凤凰城的时刻。 谁知道?

回顾 (Recap)

In this post, we’ve created a marker service that loads our data and constructs markers. We learned how to create two types of markers: L.marker and L.circleMarker. Finally, we learned how to define the size of each circle marker by passing a function for the radius.

在本文中,我们创建了一个标记服务,用于加载数据并构造标记。 我们学习了如何创建两种类型的标记: L.markerL.circleMarker 。 最后,我们学习了如何通过传递半径函数来定义每个圆形标记的大小。

In the next post, we’ll add some interactivity to our markers.

在下一篇文章中,我们将为标记添加一些交互性。

Happy mapping!

祝您映射愉快!

其他资源 (Additional Resources)

翻译自:

angular id标记

转载地址:http://aohgb.baihongyu.com/

你可能感兴趣的文章
postgres出现Server doesn't listen错误解决办法
查看>>
linux shell学习--awk练习
查看>>
敏捷开发一千零一问系列之十二:敏捷实施的步骤?
查看>>
TCP三次握手机制中的seq和ack
查看>>
java内部类的定义原则
查看>>
2017年11月26日 C#流&&窗体对话框
查看>>
endl与\n的区别
查看>>
进程和线程概念及原理
查看>>
Dubbo超时重试机制带来的数据重复问题
查看>>
注解配置里的几个注解
查看>>
使ie678支持css3伪类选择器的插件
查看>>
题解报告:hdu 1212 Big Number(大数取模+同余定理)
查看>>
POJ 3624 Charm Bracelet
查看>>
ZOJ 2314 Reactor Cooling
查看>>
关于做事的一点想法
查看>>
程序在本地能启动而预发布不能启动
查看>>
Lucene、ES好文章
查看>>
有关定时器setTimeout()、setInterval()详解
查看>>
刷题总结——次小生成树(bzoj1977 最小生成树+倍增)
查看>>
html5-2 html实体和颜色有哪些
查看>>