你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

教程:使用 Microsoft Fabric 笔记本中的“对齐道路”分析行程数据

“贴靠道路”是 Azure Maps 的一项服务,可以处理沿路线收集的 GPS 点集,并将它们贴靠到车辆行驶过的最可能的道路上。 这一功能在确定车辆的精确行驶路径时非常有用,即使收集到的 GPS 数据存在轻微偏差。

本教程讲解如何使用 Azure Maps 的贴靠道路 API 与 Microsoft Fabric 来分析移动资产的 GPS 数据,即使这些数据因信号丢失而不够准确或完整。 它将指导如何从 Microsoft Fabric 笔记本调用 Azure Maps 的贴靠道路 API,将 GPS 点贴靠到最近的道路上,使用插值数据点填充缺失的点,并通过添加道路名称和限速等额外属性来增强这些数据。

在本教程中,将:

先决条件

注意

有关 Azure Maps 中身份验证的详细信息,请参阅在 Azure Maps 中管理身份验证

创建 Microsoft Fabric 笔记本和湖屋

按照以下步骤创建 Microsoft Fabric 笔记本:

  1. 转到“我的工作区”并选择“新建项”。

    Microsoft Fabric 中“我的工作区”页面的屏幕截图,其中突出显示了“新建项”按钮。

  2. 当“新建项”屏幕出现时,向下滚动并选择“笔记本”。

    显示 Microsoft Fabric 中“新建项”屏幕中的笔记本选项的屏幕截图。

  3. 在笔记本资源管理器屏幕中,选择湖屋箭头 >

    显示选择湖屋箭头的屏幕截图。

  4. 选择“添加”按钮。

    显示“添加湖屋”按钮的屏幕截图。

  5. 在“添加湖屋”对话框中,选择“新建湖屋”,然后选择“添加”按钮。

  6. 在“新建湖屋”对话框中,输入名称“Azure_Maps_Data”,然后选择“创建”按钮。

将数据文件添加到湖屋

贴靠道路采用 GPS 点数据(lat、lon),并返回一个对象列表,这些对象构成在地图上贴靠道路的路线。 可将包含所需 GPS 数据的数据文件作为文件添加到湖屋,并由笔记本中的 python 代码引用。

下载数据文件

将示例数据 (mockData_20240919.csv) 从 GitHub 下载到本地存储设备,以在下一部分中上传到湖屋。 此文件包含一组 GPS 坐标,贴靠道路服务根据需要进行修改,以确保每个坐标指向有效的道路。

  1. 在 GitHub 中打开文件 mockData_20240919.csv

  2. 选择屏幕右上角的“下载原始文件”按钮,在本地保存文件。

    显示如何从 GitHub 存储库下载名为 mockData_20240919.csv 的数据文件的屏幕截图。

将数据文件上传到湖屋

以下步骤说明如何将数据源添加到湖屋。

  1. 从湖屋中的“文件”文件夹选择“上传”>“上传文件”。

    显示“上传文件”菜单选项的屏幕截图。

  2. 通过选择“文件夹”图标来打开文件打开对话框。 选择在上一部分下载的 mockData_20240919.csv 文件,然后选择“打开”按钮。 在文件打开对话框关闭并且上传文件控件中显示正确的文件名后,选择“上传”按钮以将文件上传到湖屋中。

    显示上传文件面板的屏幕截图。

将代码添加到笔记本

需要将四个代码单元添加到笔记本中,以执行“贴靠道路”方案。 以下部分将引导你完成此操作。

安装包

首先需要加载所需的包:

!pip install geopandas
!pip install geojson

在笔记本的第一个单元中输入 pip install 语句,然后选择运行箭头来执行这些语句

显示笔记本单元格中的安装包代码的屏幕截图。

加载数据

接下来,加载之前上传到湖屋的示例数据。

  1. 将指针悬停在用于安装包的单元格正下方。 显示用于添加代码或 Markdown 的选项。 选择“代码”以将另一个代码单元格添加到笔记本。

    显示笔记本中的添加代码链接的屏幕截图。

  2. 创建新单元格后,添加以下代码。

    import geopandas as gpd
    import pandas as pd
    
    lakehouseFilePath = "/lakehouse/default/Files/"
    
    mockdata_df = gpd.read_file(lakehouseFilePath + "mockData_20240919.csv")
    mockdata_df = gpd.GeoDataFrame(
        mockdata_df, geometry=gpd.points_from_xy(mockdata_df.longitude, mockdata_df.latitude), crs="EPSG:4326"
    )
    
    mockdata_df.head()
    
    mockdata_df.tripID.unique()
    
  3. 选择运行箭头来执行代码。 这会加载示例数据。

使用“贴靠道路”进行增强

此笔记本单元格中的代码从湖屋中的数据文件中读取原始 GPS 数据,并将其传递给 Azure Maps 贴靠道路 API。 启用内插后,API 会在 GPS 位置之间添加点,以完成沿路的路线路径。 它还提供道路名称和速度限制等属性(如果可用)。

  1. 将指针悬停在用于在上一步中安装包的单元格正下方。 显示用于添加代码或 Markdown 的选项。 选择“代码”以将另一个代码单元格添加到笔记本。

  2. 创建新单元格后,添加以下代码。 确保添加订阅密钥。

    import requests
    import json
    
    az_maps_subkey = ""
    az_maps_snaproads_url = "https://atlas.microsoft.com/route/snapToRoads?api-version=2025-01-01&subscription-key=" + az_maps_subkey
    
    # Function to process snap to road for each given trip
    def process_route(df, outputFilePath):
        # List to store successful responses
        successful_responses = []
    
        # Function to send a chunk of features
        def send_chunk_snaproads(chunk):
            geojson_data = chunk.to_json()
            # Convert the JSON string to a Python dictionary
            geojson_dict = json.loads(geojson_data)
    
            # Add the new fields at the end of the dictionary
            geojson_dict['includeSpeedLimit'] = True
            geojson_dict['interpolate'] = True
            geojson_dict['travelMode'] = "driving"
    
            # Convert the dictionary back to a JSON string
            updated_geojson_data = json.dumps(geojson_dict)
    
            response = requests.post(
            az_maps_snaproads_url, 
            headers={'Content-Type': 'application/json'}, 
            data=updated_geojson_data
            )
    
            if response.status_code == 200:
                print('Chunk request was successful...')
                successful_responses.append(response.json())
            else:
                print(f'Failed to send request. Status code: {response.status_code}')
                print('Response body:', response.text)
    
        # Loop over the GeoDataFrame in chunks of 100
        chunk_size = 100
        for start in range(0, len(df), chunk_size):
            end = start + chunk_size
            chunk = df.iloc[start:end]
            send_chunk_snaproads(chunk)
    
        # Extract features with geometry from successful responses
        features_with_geometry = []
        for response in successful_responses:
            if 'features' in response:
                for feature in response['features']:
                    if 'geometry' in feature:
                        longitude = feature['geometry']['coordinates'][0]
                        latitude = feature['geometry']['coordinates'][1]
                        feature['properties']['latitude'] = latitude
                        feature['properties']['longitude'] = longitude
                        features_with_geometry.append(feature)
    
        # Convert the list of features with geometry to a GeoDataFrame
        if features_with_geometry:
            responses_gdf = gpd.GeoDataFrame.from_features(features_with_geometry)
    
            # Write successful responses to a cvs file
            #responses_gdf.to_file(outputFilePath, driver='GeoJSON')
            responses_gdf.to_csv(outputFilePath, encoding='utf-8', index=False)
    
            print(f'Successful responses written to {outputFilePath}')
        else:
            print('No valid features with geometry found in the responses.')
    
  3. 选择运行箭头来执行代码

使用增强型数据创建文件

以下代码采用在上一个代码单元中创建的输出,并在湖屋中创建名为“SnapRoadResponses.csv”的新 CSV 文件。 此新数据文件包含更新的 GPS 坐标,这些坐标与相应的道路对齐,它还包括街道名称和速度限制(如果可用)。 “SnapRoadResponses.csv”将导入到事件屋中,并用于在本教程后面创建地图视觉对象

  1. 将指针悬停在上一步中使用“贴靠道路”进行增强的单元格下方。 显示用于添加代码或 Markdown 的选项。 选择“代码”以将另一个代码单元格添加到笔记本。

  2. 创建新单元格后,添加以下代码。

    lakehouseFilePath = "/lakehouse/default/Files/"
    #execute snap to road
    outputFilePath = lakehouseFilePath + "SnapRoadResponses" + ".csv"
    df = mockdata_df.sort_values(by='timeStamp').reset_index(drop=True)
    process_route(df, outputFilePath)
    
  3. 选择运行箭头来执行代码。 这会将包含更新 GPS 坐标的“SnapRoadResponses.csv”保存到湖屋

提示

如果在运行笔记本代码后未显示新文件,可能需要刷新浏览器。

复制文件路径

本教程稍后在创建事件屋时需要“SnapRoadResponses.csv”的 ABFS 路径。 若要获取此文件的 ABFS 路径,请选择文件旁边的省略号(...),然后从弹出菜单中选择“复制 ABFS 路径”。 复制后,请保存供以后使用。

显示如何将 ABFS 路径复制到湖屋中存储的数据文件的屏幕截图。

创建事件屋以管理车队或移动设备的遥测数据。 默认情况下会自动创建 KQL 数据库。 在本教程中,你会将贴靠数据从湖屋导入到 KQL 数据库。 若要进行实时分析,请添加流式处理数据。 上传数据后,可以在 KQL 查询集中使用 Kusto 查询语言查询数据。

  1. 转到“我的工作区”并选择“新建项”。

  2. 当“新建项”屏幕出现时,向下滚动并选择“事件屋”。

  3. 在“新建事件屋”屏幕中,输入新事件屋的名称,例如“SnapToRoadDemo”

    接下来,将之前创建的湖屋链接到新的事件屋。

  4. 选择新事件屋旁边的省略号,然后从弹出菜单中选择“获取数据”>“OneLake”。

    显示弹出菜单中 OneLake 的屏幕截图。

  5. 选择“新建表”,将其命名为 GPSData,然后选择“下一步”。

    显示“新建表”选项的屏幕截图。

  6. 在 OneLake 文件控件中输入之前保存的湖屋数据文件 (SnapRoadResponses.csv) 的 ABFS 路径,然后选择加号 (+) 将其添加到列表中。

    显示输入 OneLake 文件名的屏幕截图,其中突出显示了下一个按钮。

  7. 选择下一步

  8. 验证“检查数据”屏幕中的数据后,选择“完成”。

    显示“检查数据”屏幕的屏幕截图。

  9. 选择“关闭”以关闭“摘要”页。

    显示“获取数据摘要”屏幕的屏幕截图。

事件屋此时应已创建并包含 GPS 数据。

显示具有 GPS 数据的事件屋的屏幕截图。

创建实时仪表板

可以创建实时仪表板以连接到事件屋中的数据集。 本教程中的输入是静态数据,而不是实时流,但仪表板中的磁贴(如 Azure Maps 视觉对象)可用于视觉表示和分析。

添加数据源

  1. 转到“我的工作区”并选择“新建项”。

  2. 当“新建项”屏幕出现时,搜索或向下滚动并选择“实时仪表板”。

  3. 在“新的实时仪表板”屏幕中,输入名称 SnapToRoadDashboard,然后选择“创建”。

  4. 在“新的实时仪表板”屏幕中,选择“新数据源”。

  5. 选择“添加”按钮,然后选择“OneLake 数据中心”。

    显示实时仪表板添加数据源屏幕的屏幕截图。

  6. 选择数据源,然后选择“连接”。

    显示所选数据文件的屏幕截图,其中突出显示了“连接”按钮。

  7. 输入“显示名称”,然后选择“添加”。

    显示“创建新数据源”屏幕的屏幕截图,其中突出显示了“添加”按钮。

  8. 关闭“数据源”面板。

现在,你已为实时仪表板添加了数据源,接下来可以添加查询和地图视觉对象。

添加查询和映射视觉对象

  1. 选择“添加磁贴”。

    突出显示“添加图块”按钮的屏幕截图。

  2. 在查询中输入 GPSData,然后选择“运行。 验证查询是否正常工作后,选择“添加视觉对象”。

    显示运行查询屏幕中结果的屏幕截图。

  3. 在“视觉对象格式设置”面板中,从“视觉对象类型”下拉列表中选择“映射”。

  4. 接下来,在“数据”部分中设置值:

    数据设置 价值
    按位置定义 维度和经度
    纬度列 纬度(实数)
    经度列 纬度(实数)
  5. 从“标签列”下拉列表中选择值来更新地图信息卡。 选择“SpeedLimitInKilometersPerHour”。

  6. 选择“应用更改”

将显示地图视觉对象。 可以在地图上选择任意一点,以获取该地点的坐标以及每小时的速度限制(公里)

显示已完成地图视觉对象的屏幕截图,其中显示了显示每小时速度限制的信息卡。

后续步骤

详细了解 Microsoft Fabric 笔记本:

本教程创建了一个用于行程后路线分析的仪表板。 有关在 Microsoft Fabric 中构建实时仪表板的分步指南: