作者:Lzzzz

前言

在智慧交通、物流监控、车辆管理等场景中,原始 GPS 数据受信号漂移、高楼遮挡、隧道干扰等因素影响,会出现偏离实际道路跳跃漂移等问题,直接使用会导致路径分析、里程计算、行为识别等业务结果失真。

路网匹配(Map Matching) 是解决这一问题的核心技术,通过算法将离散 / 连续的 GPS 点绑定到真实路网数据上,实现轨迹纠偏、路径还原。本文基于SuperMap iObjects Java 12.0,实现 GPS 轨迹路网匹配与纠偏,包含环境配置、数据准备、核心代码、纠偏结果全流程。

一、技术与环境准备

1. 核心技术栈

  • 开发工具:IDEA/Eclipse
  • GIS 引擎:SuperMap iObjects Java 12.0(桌面 / 组件版)
  • 数据格式:路网、GPS 点 / 轨迹数据

2. 环境配置

  1. 下载并安装 SuperMap iObjects Java 12.0,配置Bin目录到系统环境变量;
  2. IDEA 中引入依赖库: SuperMap iObjects Java 12.0/Bin 下所有 jar 包;
  3. 初始化 SuperMap 许可(试用许可 / 正式许可)。

3. 数据准备

  • 路网数据:网络数据集,包含道路 ID、道路名称、道路等级等字段;
  • GPS数据:点数据集,包含经度、纬度、时间戳、车辆 ID 等字段;
  • SCC模型:用网络数据构建导航模型文件ssc,注"道路等级"为必填字段,且为整型,且值不为空

二、核心代码实现

1. 核心依赖导入

import com.supermap.analyst.networkanalyst.MapMatching;
import com.supermap.analyst.networkanalyst.MapMatchingResult;
import com.supermap.analyst.networkanalyst.SSCPathAnalystSetting;
import com.supermap.analyst.networkanalyst.TrackPoint;
import com.supermap.data.*;

2. 获取工作空间与数据源

String workspacePath = "E:\\MapData\\202603\\gps\\data\\WorkSpace.smwu";
WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo(workspacePath);
workspaceConnectionInfo.setType(WorkspaceType.SMWU);
Workspace workspace = new Workspace();
workspace.open(workspaceConnectionInfo);

Datasources datasources = workspace.getDatasources();
Datasource datasource = datasources.get("test");

DatasetVector netWork = (DatasetVector) datasource.getDatasets().get("network"); // 路网数据集

DatasetVector gpsPoint = (DatasetVector) datasource.getDatasets().get("gpsPoint");
DatasetVector resultPoint = (DatasetVector) datasource.getDatasets().get("resultPoint");

3. 路网匹配与轨迹纠偏核心方法

//设置SCC文件路径
String sscPath = "E:\\MapData\\202603\\gps\\data\\test.ssc";
//设置路径规划环境
SSCPathAnalystSetting SSCSetting = new SSCPathAnalystSetting();
SSCSetting.setNetworkDataset(netWork);
SSCSetting.setSSCFilePath(sscPath);
SSCSetting.setTolerance(0.1);

// GPS预处理参数设置
MapMatching mapmatch = new MapMatching();
mapmatch.setPathAnalystSetting(SSCSetting);
mapmatch.setMaxLimitedSpeed(300);
mapmatch.setMeasurementError(1500);

//从数据集中获取轨迹点
List<TrackPoint> coordinates = getTrackPointFromDataset(gpsPoint, "TimeInfo");

//进行地图匹配
MapMatchingResult result = mapmatch.batchMatch(coordinates);

三、纠偏结果

  • 匹配前

  • 匹配后

四、完整代码/示例数据

示例数据: https://download.csdn.net/download/supermapsupport/92749872

package com.supermap;

import com.supermap.analyst.networkanalyst.MapMatching;
import com.supermap.analyst.networkanalyst.MapMatchingResult;
import com.supermap.analyst.networkanalyst.SSCPathAnalystSetting;
import com.supermap.analyst.networkanalyst.TrackPoint;
import com.supermap.data.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        openWorkspace();
    }

    /**
     * 打开文件型的工作空间
     */
    public static void openWorkspace() {
        try {
            String workspacePath = "E:\\MapData\\202603\\gps\\data\\WorkSpace.smwu";
            WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo(workspacePath);
            workspaceConnectionInfo.setType(WorkspaceType.SMWU);
            Workspace workspace = new Workspace();
            workspace.open(workspaceConnectionInfo);

            Datasources datasources = workspace.getDatasources();
            Datasource datasource = datasources.get("test");

            DatasetVector netWork = (DatasetVector) datasource.getDatasets().get("network"); // 路网数据集

            DatasetVector gpsPoint = (DatasetVector) datasource.getDatasets().get("gpsPoint");
            DatasetVector resultPoint = (DatasetVector) datasource.getDatasets().get("resultPoint");

            //设置SCC文件路径
            String sscPath = "E:\\MapData\\202603\\gps\\data\\test.ssc";
            //设置路径规划环境
            SSCPathAnalystSetting SSCSetting = new SSCPathAnalystSetting();
            SSCSetting.setNetworkDataset(netWork);
            SSCSetting.setSSCFilePath(sscPath);
            SSCSetting.setTolerance(0.1);

            // GPS预处理参数设置
            MapMatching mapmatch = new MapMatching();
            mapmatch.setPathAnalystSetting(SSCSetting);
            mapmatch.setMaxLimitedSpeed(300);
            mapmatch.setMeasurementError(1500);

            //从数据集中获取轨迹点
            List<TrackPoint> coordinates = getTrackPointFromDataset(gpsPoint, "TimeInfo");

            //进行地图匹配
            MapMatchingResult result = mapmatch.batchMatch(coordinates);

            Point2D[] rectifiedPoints = result.getRectifiedPoints();

            //把匹配结果放入结果数据集中
            genResultDataset(resultPoint, rectifiedPoints);
            // 释放分析对象
            SSCSetting.dispose();
            mapmatch.dispose();
            workspace.getDatasources().closeAll();
            workspace.dispose();
        } catch (UnsatisfiedLinkError e) {
            System.out.println(e.getMessage());
        }

    }

    private static void genResultDataset(DatasetVector resultPoint, Point2D[] rectifiedPoints) {
        resultPoint.truncate();
        System.out.println("纠偏完成准备更新,点数:" + rectifiedPoints.length);
        Recordset recordset = resultPoint.getRecordset(false, CursorType.DYNAMIC);
        for (Point2D rectifiedPoint : rectifiedPoints) {
            System.out.println(rectifiedPoint);
            GeoPoint geoPoint = new GeoPoint(rectifiedPoint);
            recordset.addNew(geoPoint);
            recordset.update();
        }
        recordset.close();
        recordset.dispose();
        resultPoint.dispose();
    }

    public static List<TrackPoint> getTrackPointFromDataset(DatasetVector dataset, String s) {
        List<TrackPoint> points = new ArrayList<>();
        // 点集合
        if (dataset.getType() == DatasetType.POINT) {
            int count = dataset.getRecordCount();
            Recordset recordset = dataset.getRecordset(false, CursorType.STATIC);
            recordset.moveFirst();
            for (int i = 0; i < count; i++) {
                TrackPoint point = new TrackPoint();
                Point2D pt = recordset.getGeometry().getInnerPoint();
                point.setPoint(pt);
                point.setTime((Date) recordset.getFieldValue(s));
                points.add(point);
                recordset.moveNext();
            }
            recordset.dispose();
            return points;
        }
        return null;
    }
}

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐