使用 Vaadin Directory 组件显示Google地图 - day27

目的

地图反查经纬度,将地图显示在立委服务地区旁。
https://ithelp.ithome.com.tw/upload/images/20211012/20138680YKzMtZMDsX.png
https://ithelp.ithome.com.tw/upload/images/20211012/20138680BByZxn72xA.png

本篇重点:

  • 导入Vaadin direction组件 Google Maps Addon
  • 地址查座标
  • 地图显示

本示例使用 Google Maps Addon 套件最基本功能 : 使用街道地图、将地图移到座标中心点、地图放大、加地图标记。从上方执行结果可看到执行结果,地图可切换全萤幕显示、zoom in/out、地图显示模式切换、街景服务,功能相当完备。

Vaadin Directory

Vaadin Directory 内有大量开源组件,笔者在本系列文首篇简介里提到,Vaadin Directory 内已有近2000个组件。当开发出满意的组件时,也可自由上传供其他人使用。
https://ithelp.ithome.com.tw/upload/images/20211012/20138680QWNHDhTz29.png

Google Maps Addon

https://ithelp.ithome.com.tw/upload/images/20211012/20138680hQFONRb0fG.png
通常 add-on 只提供 Maven dependency 如下,但本专案为 Gradle 专案,须转换一下。

<dependency>
   <groupId>com.flowingcode.vaadin.addons</groupId>
   <artifactId>google-maps</artifactId>
   <version>1.4.0</version>
</dependency>
<repository>
   <id>vaadin-addons</id>
   <url>https://maven.vaadin.com/vaadin-addons</url>
</repository>

准备工作

导入 Gradle 专案

repository

    repositories {
        maven("https://maven.vaadin.com/vaadin-addons")
        mavenCentral()
        google()
    }

dependency

因本套件使用 Google Map,所以除了Google Maps Addon外,还要导入Google Maps Services

implementation("com.flowingcode.vaadin.addons:google-maps:1.4.0")
implementation("com.google.maps:google-maps-services:1.0.0")

启用 Google API

使用 Google 地图服务需要启用帐单收费功能,请留意收费标准
地址查经纬度 : Geocoding API
https://ithelp.ithome.com.tw/upload/images/20211012/20138680WQN6KyWhzL.png
网页显示地图 : Maps JavaScript API
虽然Vaadin使用kotlin开发,但别忘了,它毕竟是web application
https://ithelp.ithome.com.tw/upload/images/20211012/201386807XrEU6lk7H.png

取得 API Key

请参考官网文件
https://ithelp.ithome.com.tw/upload/images/20211012/20138680QQHAvnacf3.png

地图显示

地址查经纬度座标

这部份在很多地方都可查到上传格式,在此不多加叙述,或者您可参考官网文件。本文取得座标方法在下方。

回传内容格式

Geocoding API response json 如下,但我们需要的只有下述打 * 号的部份

{
  "addressComponents": [
    {
      "longName": "165",
      "shortName": "165",
      "types": [
        "STREET_NUMBER"
      ]
    },
    {
      "longName": "Section 4, Fengyuan Boulevard",
      "shortName": "Section 4, Fengyuan Blvd",
      "types": [
        "ROUTE"
      ]
    },
    {
      "longName": "北阳里",
      "shortName": "北阳里",
      "types": [
        "ADMINISTRATIVE_AREA_LEVEL_4",
        "POLITICAL"
      ]
    },
    {
      "longName": "Fengyuan District",
      "shortName": "Fengyuan District",
      "types": [
        "ADMINISTRATIVE_AREA_LEVEL_3",
        "POLITICAL"
      ]
    },
    {
      "longName": "Taichung City",
      "shortName": "Taichung City",
      "types": [
        "ADMINISTRATIVE_AREA_LEVEL_1",
        "POLITICAL"
      ]
    },
    {
      "longName": "Taiwan",
      "shortName": "TW",
      "types": [
        "COUNTRY",
        "POLITICAL"
      ]
    },
    {
      "longName": "420",
      "shortName": "420",
      "types": [
        "POSTAL_CODE"
      ]
    }
  ],
  "formattedAddress": "No. 165, Section 4, Fengyuan Blvd, Fengyuan District, Taichung City, Taiwan 420",
  "geometry": {
*    "location": {
*      "lat": 24.2467722,
*      "lng": 120.73373
*    },
    "locationType": "ROOFTOP",
    "viewport": {
      "northeast": {
        "lat": 24.2481211802915,
        "lng": 120.7350789802915
      },
      "southwest": {
        "lat": 24.2454232197085,
        "lng": 120.7323810197085
      }
    }
  },
  "types": [
    "STREET_ADDRESS"
  ],
  "partialMatch": false,
  "placeId": "ChIJVfZYFhgaaTQRxZpdnhApIp4",
  "plusCode": {
    "globalCode": "7QP26PWM+PF",
    "compoundCode": "6PWM+PF Fengyuan District, Taichung City, Taiwan"
  }
}

使用 Google Maps Services API 查座标,取得 location

    private fun getLatLng(addr: String): LatLng {
        val context = GeoApiContext.Builder()
            .apiKey(apiKey)
            .build()
        val result = GeocodingApi.geocode(context, addr).await()
        val gson = GsonBuilder().setPrettyPrinting().create()
        return result[0].geometry.location
    }

显示地图组件

此自制组件传入参数为地址,透过geocoding api查询经纬度座标,再显示地图。一般实务上不这麽使用,通常会储存查到的座标,节省重复查询流量。

本示例使用 Google Maps Addon 套件最基本功能 : 使用街道地图、将地图移到座标中心点、地图放大、加地图标记。

class GoogleMapComponent(addr: String) : KComposite() {
    private lateinit var gmaps: GoogleMap
    private val apiKey = "AIzaSyD.............wXyRDoA"

    private val root = ui {
        verticalLayout {
            val latLng = getLatLng(addr)
            val latlon = LatLon(latLng.lat, latLng.lng)

            gmaps = GoogleMap(apiKey, null, null).apply {
                mapType = GoogleMap.MapType.ROADMAP
                zoom = 15
                center = latlo
                addMarker("Center", center, true, "")
                setSizeFull()
            }
            add(gmaps)
        }
    }
}

fun HasComponents.googleMapComponent(addr: String, block: GoogleMapComponent.() -> Unit = {}) = init(GoogleMapComponent(addr), block)

在 ui 上显示地图

   horizontalLayout.add([email protected](addr)

<<:  【资料视觉化】COVID新冠疫苗施打一览 Seaborn

>>:  Day-28 : Model 多对多

(後记) 突破一般视讯会议限制的视讯设备

当疫情不止,行销活动还是要想办法办下去,而举办视讯会议已经不能像以往只在一般的会议室,各种的场地都要...

Alpine Linux Porting (2.1) clock is _not_ ticking

这篇开始基本上是进入持续分析有哪些未完善的部份需要进行补足。 依照这几次的bootlog的部份分析,...

[Day 17] Mattermost - 介绍与安装

mattermost 什麽是mattermost 它是OpenSource、可自行架设的线上聊天服务...

Ruby 最佳实践

概述 Ruby 程序语言的安全性原则,主要聚焦於 Ruby on Rails Web 框架。 注意事...

[第27天]30天搞懂Python-序列化

前言 使用python原生之pickle函式库进行序列化。 程序实作 提供一个年龄资料集,来实作序列...