在 Kibana 地图中使用外部地图数据和 ES|QL

2025年2月6日   |   by mebius

作者:来自 ElasticMichael_Bischoff

简介

今天我想谈谈 Kibana 地图,因为它有时被忽视为一种可视化。这是因为在仪表板的背景下,我们似乎习惯于考虑图形、数字和表格。地图可视化未被使用的其他原因是,它可能看起来难以配置,或者假设没有正确的数据。通过提供示例,我们希望提供想法,通过提供示例降低门槛并鼓励更多地使用它。

除了地图很棒之外,我们还想调用公开可用的地图服务和数据集。我们将演示如何包含它们,并希望激励您自己寻找数据集和来源,以进一步丰富你的体验并提供对数据的新见解。

导航到地图

首先,我们需要进入地图应用程序。在当前最新版本 (8.17) 中,导航到地图应用程序略有不同,在以前的版本中,可以在以下位置找到:

Main menu -> Analytics -> Maps。

在 8.17 中,它取决于解决方案:

  • Search:
    • Main navigation -> Other tools -> Maps
  • Observability:
    • Main navigation -> Other tools -> Maps
  • Security:
    • Main navigation -> Stack Management -> (Kibana section) Maps

也可以从仪表板创建地图:

  • Dashboards -> Create Dashboard (right top) -> Add panel -> Maps

图层

创建地图后,你将获得一个名为 “Basemap” 的图层,该图层已包含一些有用信息。在起始缩放级别,你将看到国家/地区的轮廓和名称,甚至可能是地区或城市名称。但是,随着放大,会添加更多细节,一直到建筑物和街道。平衡屏幕上的空间与显示的信息或详细信息是保持可管理性的重要方法。通过使图层可见或在特定缩放级别隐藏它们,可以重新创建体验。但是,为了限制本文的范围,我们不会配置缩放级别。

公开可用的数据源

Basemap 基于 Elastic Maps Service 提供的 OpenStreetMap 和 OpenMapTile 数据。请注意右下角的 “Attribution”。我们将展示如何为你的图层设置此属性,这可能是使用某些公共来源的必要条件。

%title插图%num

有大量的公开地理数据 – 具有各种质量和可靠性水平。公共部门发布的数据往往在质量和可靠性方面得tgcode分较高。请遵守其使用要求(例如 attribution),并注意速率限制,并在与(较大)用户组共享仪表板时考虑部署缓存代理。

Kibana 可以处理与这些数据集交互的各种方式,在这里我们将演示 Web 地图服务 (WMS)、geojson、csv 和 ndjson 文件的使用。这些也往往是寻找公共地理数据集时要使用的关键字。

“我梦想着一个白色的圣诞节”(Web Map Service – WMS)

每年人们都会想知道今年圣诞节会下雪吗?那就跳过天气预报,让我们启动 Kibana!

创建一个新地图,然后单击右侧的彩色 “add layer” 按钮:

%title插图%num

然后选择 WMS 层(你可能需要向下滚动):

%title插图%num

然后我们可以在这里输入 WMS 服务 URL。我们将使用以下 URL:

https://mapservices.weather.noaa.gov/vector/services/precip/wpc_prob_winter_precip/MapServer/WMSServer?request=GetCapabilities&service=WMS

这是从 https://www.weather.gov/gis/cloudgiswebservices的天气预报中心Current Weather and Forecast Products and Services -> Probabilistic Winter Precipitation 下检索到的。如果你不介意在雪中行走,也可以在那里找到不同的服务。

输入 URL 后,我们可以单击 “Load capabilities” 按钮。

%title插图%num

这应该会显示 Kibana 从 URL 加载的图层和样式下拉菜单。让我们选择所有 “Day 1” 图层和样式:

%title插图%num

然后点击 “Add an continue”。然后我们可以命名图层并添加 attribute:

%title插图%num

%title插图%num

太好了,我们现在应该在地图上看到天气预报了,我们可以保存地图以便以后调用。

%title插图%num

%title插图%num

如果你像我们大多数人一样尝试添加所有图层和样式,你可能会注意到它变得有点混乱。为了解决这个问题,并能够每天切换,我们建议创建两个额外的图层,并在以后的每一天进一步降低图层的不透明度:

%title插图%num

在上面,我们按照同样的方法把 Day 2 及 Day 3 的图添加进去。

目前,预计两三天后北达科他州和缅因州将迎来降雪。

注意:除了样式(通常只有一种)之外,WMS 服务不允许对数据显示方式进行太多自定义。不透明度可用于淡化图层。此外,WMS 图层提供了时间快照。这使得解释历史数据变得困难。最后,WMS 图层不允许与其他数据集交互,我们将在下一节中介绍替代方案。

“下雪吧,下雪吧,下雪吧”(加载 geojson)

到目前为止,我们一直避免将数据加载到 Elasticsearch 中,因为根据你的设置,用户可能不被允许索引数据。接下来,我们将展示如何加载 geojson 数据,这将为我们提供新的选择。

为了获取数据,我们将使用 WFS 服务。我们之前使用的数据集也通过 WFS 服务公开:

https://mapservices.weather.noaa.gov/vector/services/precip/wpc_prob_winter_precip/MapServer/WFSServer?request=GetCapabilities&service=WFS

GetCapabilities 请求类型不会直接返回地理数据,而是描述服务公开的内容。

https://mapservices.weather.noaa.gov/vector/services/precip/wpc_prob_winter_precip/MapServer/WFSServer?request=GetFeature&service=WFS&outputFormat=GEOJSON&typeNames=wpc_prob_winter_precip:Day_1_probability_of_at_least_4_inches_of_snow&srsName=EPSG:4326

..或作为可点击的超链接..

(输出格式已更改为 GEOJSON+ZIP 链接。这样,我们可以节省一些带宽,而且不会最终离开)

如果你只想做示例,则可以跳过下一部分,但如果你想自己使用其他来源,则以下部分可能会有用:(你可以跳到此处

让我们看一下请求中使用的参数:

Parameter Value
service WFS
request GetFeature
outputFormat GEOJSON
typeNames wpc_prob_winter_precip:Day_1_probability_of_at_least_4_inches_of_snow
srsName EPSG:4326

service 参数应始终为 WFS(如 GetCapabilities URL),如果你以 GetCapabilities URL 为起点,则应将请求更改为 GetFeature 以替换 GetCapabilities。

outputFormat 可能是 GEOJSON、application/geo+json、application/json; subtype=geojson 甚至只是 json 或 application/json。要获取正确的值,你应该检查 GetCapabilities URL 返回的 xml 并查找 元素,该元素应具有一个 元素,其中包含 以及服务可以理解的值。请确保对参数进行编码,因此 application/json; subtype=geojson 变为 application%2Fjson%3B%20subtype%3Dgeojson

与 outputFormat 类似,typeNames 选项可以在 GetCapabilities 响应中找到。查找 并查找 FeatureType 元素下的 name 元素。

最后是 srsName。首先,让我们向你展示如果它不正确会发生什么:

%title插图%num

我们看到了南极洲海岸的多边形,这在查找美国天气预报时是意料之外的。此参数允许你指定坐标参考系。Kibana 始终期望这是 EPSG:4326,这是常用 WSG84 的 EPSG 代码。

跳到此处

下载文件后,如果需要,应解压并再次创建地图,然后单击添加图层。我们选择 Upload File:

%title插图%num

然后我们可以选择该文件并看到多边形出现在美国上方:

%title插图%num

%title插图%num

%title插图%num

%title插图%num

注意:预览仅加载一定数量的多边形。如果你缺少特征,可能是因为预览中未加载这些特征,单击 “Import file” 时它们才会显示。

我们可以继续单击 import file。文件将被上传,数据将被索引到 Elasticsearch。Kibana 将显示操作概述:

%title插图%num

我们可以通过单击 “Add as document layer ” 来继续:

%title插图%num

%title插图%num

%title插图%num

此外,我们还可以与多边形进行交互,例如添加 tooltips,也可以添加数据。我们将在下一节中展示一个示例。WMS 层的tgcode不同之处在于,通过将数据导出和导入 Elasticsearch,我们捕获了某个时刻。如果我们自动化该过程,我们可以建立历史记录并回忆任何一天。

注意:这超出了本文的范围,但作为一个实际的例子,我们可以比较有降水的日子和没有降水的日子的收入。这可能对依赖天气的活动有用。

“写给圣诞老人的信”(EMS 边界)

对于下一节,我们需要使用 Kibana 上传 ndjson 文件

注意:对于 8.17 及更高版本,它位于Management -> Integrations(右下角)下,搜索解决方案当前位于 “overview” 页面上。

%title插图%num

%title插图%num

请上传并索引:letters_to_santa_10000.ndjson

%title插图%num

%title插图%num

%title插图%num

在索引中,你会找到加拿大人写给圣诞老人的虚构信件。圣诞老人想知道哪些省收到的信件最多。我们将使用 “EMS Boundaries” 图层在地图上绘制此图层。让我们创建一个新地图并单击 add layer:

%title插图%num

%title插图%num

%title插图%num

数据由 maps.elastic.co 提供。为了满足圣诞老人的要求,我们必须合并数据。在“合并”下单击 “添加术语合并”。将显示“合并 — 配置术语合并 –”。单击它:

%title插图%num

%title插图%num

%title插图%num

For ‘Left field’ select ‘ISO 3166-2 code’
For ‘Right source’ select the index that was created when you uploaded in the file. In our case ‘letters-to-santa’
For ‘Right field’ Address.ProvinceCode.keyword

数据现已合并,我们将鼠标悬停在各省份上时,可以看到计数。在 “Tooltip fields” 下,你可以添加 “name(en)”

%title插图%num

将鼠标悬停在每个省份上很麻烦,而且不能仅通过查看地图进行解释。因此,让我们根据计数更改省份的颜色。在 “Layer style” 下,将 “Fill color” 从实心更改为“By value”。然后将 “select a field” 更改为 “count of letters-to-santa”。

然后作为最后的更改,我们将在同一部分中配置 “Label”。将 “Fixed” 更改为“按值”并选择 “name (en)”:

%title插图%num

我们现在可以点击 “Keep changes”。

%title插图%num

“圣诞老人的工作室在哪里”(ES|QL)

让我们从简单的开始,将圣诞老人的工作室添加为地图上的一个点。为此,我们将利用最近添加的 “ES|QL” 图层。要添加,请单击添加图层并选择 ES|QL:

%title插图%num

然后将显示以下输入,该输入期望 ES|QL 查询返回至少一个地理数据字段:

%title插图%num

在本节中我们可以粘贴以下 ES|QL:

ROW point = TO_GEOPOINT("POINT (0 84.8)"), label = "Santa's workshop"

这里我们定义了一个 ROW,不做任何进一步的处理,只是返回该行。该行有两列 – 或字段:point 和 label。“Point( 0 84.8)”是一个包含 WKT 的字符串。要将字符串解释为地理数据,我们将该字符串用作 TO_GEOPOINT 函数的参数。

注意:第二个数字不是 90(这会使它成为真正的北极)是因为显示原因。

我们现在可以运行查询,禁用其余设置,然后单击 “add and continue >”:

%title插图%num

%title插图%num

我们设置:

  • 图层名称。
  • 图标为 “Building 2”。
  • 标签为 “by value”,对于值我们使用 “label”。
  • 标签位置为 “Bottom”。

另请参见下图,其中的设置用红色标记:

%title插图%num

%title插图%num

这应该产生以下图像:

%title插图%num

或者,我们可以将有关圣诞老人工作室的数据作为 Elasticsearch 中的文档进行索引,然后使用 ES|QL FROM 命令。这也将允许我们显示多个点。显示带有标签的单个位置,而不必将文档索引到 Elasticsearch 中,仍然可以在紧急情况下添加一些元数据。

也许,也许将来 ROW 命令将扩展为允许指定多行。作为当前状态下的解决方法,我们可以简单地为每个实体添加一个图层,并使用 “Layer group” 图层进行分组,然后隐藏这些图层。

注意:我们将地理点从字符串转换而来。这意味着使用 ES|QL,我们可以处理未作为地理点或地理形状进行索引的数据,如果我们无法控制索引和提取,这将非常有用。还有一个缺点:在地图上移动并刷新图层时,我们无法有效地使用该字段来过滤屏幕外的对象。

“更多写给圣诞老人的信” (ES|QL)

我们也可以使用 ES|QL 层重新创建 “写给圣诞老人的信”。但是,我们需要自己下载加拿大各省数据集并上传。

步骤 1 – 下载 Elastic Maps Service 边界:

  1. 导航到 Elastic Maps Service 登陆页面
  2. 在左侧边栏中,选择一个行政边界(administrative boundary)。(在我们的例子中是 “Canadian Provinces”)
  3. 单击下载 GeoJSON 按钮。

步骤 2 – 索引 Elastic Maps Service 边界(参见“下雪吧,下雪吧,下雪吧”)

  1. 打开地图。
  2. 单击 Add layer,然后选择上传 GeoJSON。
  3. 上传 GeoJSON 文件并单击 Import file。

我们还需要一个丰富的策略来根据省份 ISO 代码查找几何图形。转到 devtools。然后输入并执行以下命令:

PUT /_enrich/policy/ca_province_lookup_geometry
{
  "match": {
    "indices": "canada_provinces_v1",
    "match_field": "iso_3166_2",
    "enrich_fields": ["iso_3166_2", "label_en", "label_fr", "geometry"]
  }
}

我们期望得到以下回应:

{
  "acknowledged": true
}

tgcode

然后执行策略:

POST /_enrich/policy/ca_province_lookup_geometry/_execute

我们期望得到以下回应:

{
  "status": {
    "phase": "COMPLETE"
  }
}

就像在 “圣诞老人的工作室在哪里” 中一样,让我们​​创建一个新的地图并添加一个 “ES|QL” 层。作为查询将输入以下内容:

FROM 	letters-to-santa
| STATS count(*) BY Address.ProvinceCode
| ENRICH ca_province_lookup_geometry ON Address.ProvinceCode

运行查询,然后单击 Add and continue

像 “给圣诞老人的信” 一样配置填充颜色:“By value” 和 “count(*)”。我们现在得到相同的结果:

%title插图%num

但我们确实获得了一些收获:我们现在可以更好地控制匹配方式。假设一个索引使用大写字母,而查找索引使用小写字母,我们可以使用字符串函数 TO_LOWER 来匹配。我们还可以使用另一个带有丰富策略的 “映射” 索引来获得更大的灵活性。

但如果我们没有加拿大各省的 ISO 代码(我们通常没有),甚至没有省名,该怎么办?ES|QL 实际上启用了我们以前没有的选项:按多边形聚合点。

为了演示,我们必须创建另一个丰富策略,这次我们将使用 geo_match:

PUT /_enrich/policy/ca_province_lookup
{
  "geo_match": {
    "indices": "canada_provinces_v1",
    "match_field": "geometry",
    "enrich_fields": ["iso_3166_2", "label_en", "label_fr", "geometry"]
  }
}

并执行策略:

POST /_enrich/policy/ca_province_lookup/_execute

如果我们现在再次创建一个带有 ES|QL 层的地图,我们可以输入以下查询:

FROM letters-to-santa
| ENRICH ca_province_lookup ON Location
| STATS count(*) BY iso_3166_2, geometry

我们不依赖地址就可以得到相同的结果:

%title插图%num

注意:这要求我们在聚合之前对每个字母进行查找,这意味着我们需要充实的文档越多,这种类型的查询将花费更长的时间。还应考虑准确性:靠近边界的位置可能无法正确匹配。具体来说,我们使用的 EMS 数据集针对显示目的进行了优化。你可以尝试放大海岸线以了解情况。

原文:Dec 20th, 2024: [EN] Using external map data and ES|QL in Kibana maps – Advent Calendar – Discuss the Elastic Stack

文章来源于互联网:在 Kibana 地图中使用外部地图数据和 ES|QL

Tags: , , ,