使用Angular在Spring Boot应用程序中集成Bing地图
我们经常发现自己需要在应用程序中整合地图。本教程将向你展示如何将Bing Maps 与Angular、Spring Boot和关系型数据库整合。
用户将能够玩转地图,在不同时间显示不同的网站属性。
教学目的
本教程将引导你了解关于[MS Bing地图]的一切,以及如何使用Angular 11、Spring Boot后台和H2/Postgres关系数据库进行整合。
前提条件
要学习这篇文章,你需要具备以下条件。
- Angular的基本知识,特别是设计RESTful端点。
- 使用[Spring Boot框架]的背景知识。
- Java Persistence API(JPA),用于在Java对象和关系型数据库之间持久保存数据。
- 必应地图门户[账户],为我们的应用地图生成API密钥。
- 基本的[liquidibase]知识。
还需要注意的是,这不是一个Angular和Spring Boot的入门教程。要跟上这个教程,你应该有一个已经启动并运行的应用程序。此外,你可以从我的GitHub仓库克隆源代码。
设置项目后端
由于我们这个项目需要一个数据库,我们将从liquibase加载我们的数据用于测试。
我们还将创建一个资源库,用来设置不同的日期来过滤数据。例如,如果我们需要2010年的数据,我们在那里设置,以此类推。
让我们看一个例子。
// defining how to retrieve site data from a repo
public interface SiteRepository extends JpaRepository<Site, Long>{
@Query("select cs from CompanySite cs where lower(cs.title) like %:title% and cs.atDate >= :from and cs.atDate <= :to")
List<Site> findByTitleFromTo(@Param("title") String title, @Param("from") LocalDate from, @Param("to") LocalDate to);
}
在上面的片段中,我们从数据库中查询数据,以检索name 和date 。
有了这个资源库,我们可以创建一个服务来加载数据,如下图所示。
public Collection<Site> findSiteByTitleAndYear(String title, Long year) {
if (title == null || title.length() < 2) {
return List.of();
}
// define beginning year of type LocalDate and endOfYear
LocalDate beginOfYear = LocalDate.of(year.intValue(), 1, 1);
LocalDate endOfYear = LocalDate.of(year.intValue(), 12, 31);
//return the result
return this.SiteRepository.findByTitleFromTo(title.toLowerCase(), beginOfYear, endOfYear);
}
现在我们已经定义了我们的资源库和服务,我们可以继续创建一个控制器并为应用程序设计我们的RESTful端点。
// in this section, we inject the previously created service in the controller
public SiteController(SiteService SiteService, EntityDtoMapper entityDtoMapper) {
this.SiteService = SiteService;
this.entityDtoMapper = entityDtoMapper;
}
// RequestMapping to get api data
@RequestMapping(value = "/title/{title}/year/{year}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<SiteDto>> getSiteByTitle(@PathVariable("title") String title,
@PathVariable("year") Long year) {
List<CSiteDto> SiteDtos = this.SiteService.findSiteByTitleAndYear(title, year)
.stream().map(Site -> this.entityDtoMapper.mapToDto(Site)).collect(Collectors.toList());
return new ResponseEntity<List<SiteDto>>(SiteDtos, HttpStatus.OK);
}
在上面的代码中,我们导入了服务并将其注入到我们的控制器中。
然后我们使用RequestMapping 注解来定义我们的RESTful端点。我们使用ResponseEntity ,以HTTP状态200 ,即OK ,返回结果。
不要忘记更新application.properties ,如下图所示。
bing.maps-key=${BINGMAPKEY:AlqIk2T-YourBingKey}
在这里获得完整的后端代码。
设置Bing地图的前端
这一部分假设你已经阅读了Bing地图的文档。
这个前端的设计使用Angular Material来显示位置和属性,如下图所示。

让我们来添加HTML 内容,我们将用它来显示我们网站的Bing地图。
<div>
<!-- the form fields(inputs)-->
<div>
<!-- BEGIN company site input field-->
<mat-form-field class="example-full-width">
<input
type="text"
placeholder="Pick one"
aria-label="Number"
matInput
formControlName="{{COMPANY_SITE}}"
[matAutocomplete]="auto"
/>
<!-- this is a material feature for input autocomplete -->
<mat-autocomplete
autoActiveFirstOption
#auto="matAutocomplete"
[displayWith]="displayTitle"
>
<mat-option
*ngFor="let option of companySiteOptions | async"
[value]="option"
>
{{option.title}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<!-- END company site input field-->
<div>
<!-- BEGIN year slider -->
<mat-slider
class="my-slider"
thumbLabel
[displayWith]="formatLabel"
step="10"
min="1970"
max="2020"
formControlName="{{SLIDER_YEAR}}"
>
</mat-slider>
<span class="my-year" i18n="@@companysite.slideryear">
Year: {{ componentForm.get('sliderYear').value }}</span
>
</div>
<!-- END year slider -->
</div>
在上面的标记中,我们使用Angular Material来设计我们的页面布局,首先是company site 输入,它有一个自动完成功能和一个输出字段year slider 。
需要注意的是,上述HTML中的Angular表单组在我们在ts 文件中定义它之前是不会起作用的,如下图所示。
//manipulte DOM elements
bingMapContainer: ElementRef;
//get new locations
newLocations: NewLocation[] = [];
map: Microsoft.Maps.Map = null;
resetInProgress = false;
//an observable to get company options
companySiteOptions: Observable<CompanySite[]>;
//a form builder for reactive forms
componentForm = this.formBuilder.group({
companySite: ['Finkenwerder', Validators.required],
sliderYear: [2020],
property: ['add Property', Validators.required]
});
在上面的代码中,我们定义了bingMapContainer ,以包裹我们的DOM元素来注入地图。我们还添加了表单生成器来为我们的Bing应用程序创建反应式表单。
总结
在本教程中,我们已经用Spring Boot和JPA H2数据库建立了一个Angular 11项目。我们看到了如何将Bing地图集成到应用程序中并在浏览器上显示。
你可以克隆该项目并测试其功能。该项目被配置为使用Gradle,这可能需要一些时间来构建,以及Kubernetes和docker。
