精华内容
下载资源
问答
  • 地图匹配技术概览 文章目录 目录 地图匹配技术概览 文章目录 前言 一、地图匹配概述 二、轨迹预处理 1.降噪 1.1 中值滤波 1.2 极值滤波 1.3 分段 1.4 插值算法 三、基于权重的地图匹配算法 3.1、...

     


    前言

    随着生活质量的日益提高,地图相关技术已经渗透到人们生活的各个角落,本文对地图匹配技术,进行简单的概述和实现,为没接触过地图开放的朋友,又想要了解相关技术的提供一个参考信息,内容有误之处,还请大神指点。

    一、地图匹配概述

     

    由于GPS技术特性原因,定位结果受客观存在的环境因素影响,我们拿到的原始轨迹数据并不是我们在轨迹结果上看到的那么整洁、规范和有序,如果直接把这些点打到地图上,那么我们的行动轨迹,可能看起来就是这样:

    所以信号也有颗不安分的心,这份轨迹数据让人看起来很灰心,因为勺子里面装了一些不该有的东西。那么我们需要通过一系列的技术手段,来保留我们想要的、看起来合理的轨迹,去掉看起来不合理的数据。

    这一系列的技术手段,包括降噪、分段、抽稀、路网匹配、轨迹补偿等,如下图

    降噪:降噪技术在数据处理方面应用得非常广泛,例如BI、机器学习等领域,数据几乎都需要进行噪点处理,降噪后的数据通常会存在多多少少的失真,这个缺陷可以通过后期的路网匹配来进行修正;

    抽稀:浮点运算是个比较消耗CPU性能的计算,我们通常需要对原始数据进行抽稀处理,将原始数据精简为足以还原轨迹的数量即可;

    路网匹配:由于信号偏移、降噪处理等因素,导致有些轨迹点是不在道路网上的,当我们把这些点打到地图上以后,会发现我们可能行走在山顶、湖泊、大海,显然这并不合理,所以我们需要结合路网数据,将轨迹拟合到道路网。

    二、轨迹预处理

    1.降噪

    剔除数据中的冗余点和噪音点,通常使用,噪音滤波技术,主要算法包括中值滤波、均值滤波、卡尔曼滤波等;

    轨迹压缩技术,通常使用道格拉斯压缩算法;

    轨迹分段技术,通常使用网格划分算法,以及角度、密度、速度相似度匹配算法

    后续小节将对各个处理节点算法进行一一详解。

    1.1 中值滤波

    当时由于项目时间原因,中值滤波算法是本次主要降噪算法,该算法在当前版本中,实现成本、学习成本、处理效果是最优选择。

    算法原理

    1、对坐标点Pi,获取前后n(n为大于2的偶数)个节点的集合R;
    2、将R的经度、纬度,分别进行正序排序;
    3、分别取经度和纬度的中间值,作为该节点的最终经度和纬度;

    图例:

    关键代码:

    / 起始索引,前面range个坐标不处理
    
    int startIndex = STEP_SIZE / 2 + 1;
    
    // 结束索引,后range个坐标不处理
    
            int endIndex = tracks.size() - STEP_SIZE / 2;
    
            // STEP_SIZE每次处理的坐标个数,除以二即为前后处理的范围
    
            int range = STEP_SIZE / 2;
    
            for (int i = startIndex; i < endIndex; i++) {
    
                UserTrackDTO track = tracks.get(i);
    
                List<Double> lngs = new ArrayList<>();
    
                List<Double> lats = new ArrayList<>();
    
                // 获取预定范围间的所有经度和纬度
    
                for (int j = i - range; j <= i + range; j++) {
    
                    lngs.add(tracks.get(j).getLngDouble());
    
                    lats.add(tracks.get(j).getLatDouble());
    
                }
    
                // 排序
    
                Collections.sort(lngs);
    
                Collections.sort(lats);
    
                // 取中间
    
                track.setLng(String.valueOf(lngs.get(3)));
    
                track.setLat(String.valueOf(lats.get(3)));
    
        }

    中值滤波的缺点:对于连续多个噪点的数据处理得并不理想,增加步长会增加时间复杂度和严重失真,后续会考虑引入卡尔曼滤波算法看看效果;

    1.2 极值滤波

    算法原理
    1、计算各个坐标点距离上一个点的距离、速度;
    2、按比例移除距离、速度较大的点;
    关键代码:

            tracks.get(0).setDistance(0);
            for (int i = 1; i < tracks.size(); i++) {
                UserTrackDTO lastTrack = tracks.get(i - 1);
                UserTrackDTO track = tracks.get(i);
                Double distance = DistanceHepler.distance(track, lastTrack);
                track.setDistance(distance.intValue());
            }
            Double maxSize = tracks.size() * 0.80D;
            tracks = tracks.stream()
                    .sorted(Comparator.comparing(UserTrackDTO::getDistance))
                    .collect(Collectors.toList());
            tracks = tracks.stream()
                    .limit(maxSize.intValue())
                    .collect(Collectors.toList());
            tracks = tracks.stream()
                    .sorted(Comparator.comparing(UserTrackDTO::getIndex))
                    .collect(Collectors.toList());

    极值滤波缺点:只能按预设定的阈值进行截取,未考虑当前路况等综合情况进行阈值的设定,会导致精确度不足;
    1.3 压缩

    算法原理
    (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦;
    (2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离d;
    (3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。
    (4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段曲线进行1~3的处理。
    (5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。
    图例:

    关键代码:

        /**
    	 * 
    	 * @param coordinate
    	 * @param dMax
    	 * @return
    	 */
    	public static List<UserTrackDTO> douglasPeucker(List<UserTrackDTO> coordinate, int dMax) {
    		// 抽稀点数量需要大于2
    		if (coordinate == null || coordinate.size() <= 2) {
    			return coordinate;
    		}
    		coordinate = checkCircle(coordinate);
    		// 起点和终点重合时,分段处理
    		int endIndex = coordinate.size() - 1;
    		List<UserTrackDTO> result = new ArrayList<>();
    		compressLine(coordinate, result, 0, endIndex, dMax);
    		result.add(coordinate.get(0));
    		result.add(coordinate.get(endIndex));
    		return result.stream()
                .sorted(Comparator.comparing(UserTrackDTO::getIndex))
                .collect(Collectors.toList());
    	}
    
    /**
    	 * 递归方式压缩轨迹
    	 * 
    	 * @param coordinate
    	 * @param result
    	 * @param start
    	 * @param end
    	 * @param dMax
    	 * @return
    	 */
    	private static void compressLine(List<UserTrackDTO> coordinate, List<UserTrackDTO> result, int start, int end, int dMax) {
    		if (start < end) {
    			double maxDist = 0;
    			int currentIndex = 0;
    			UserTrackDTO startPoint = coordinate.get(start);
    			UserTrackDTO endPoint = coordinate.get(end);
    			for (int i = start + 1; i < end; i++) {
    				double currentDist = distToSegment(startPoint, endPoint, coordinate.get(i));
    				if (currentDist > maxDist) {
    					maxDist = currentDist;
    					currentIndex = i;
    				}
    			}
    			if (maxDist >= dMax) {
    				// 将当前点加入到过滤数组中
    				result.add(coordinate.get(currentIndex));
    				// 将原来的线段以当前点为中心拆成两段,分别进行递归处理
    				compressLine(coordinate, result, start, currentIndex, dMax);
    				compressLine(coordinate, result, currentIndex, end, dMax);
    			}
    		}
    	}
    

    这个算法处理环形轨迹的时候,会将整条轨迹全部精简掉,所以这里用到分段技术。

    1.3 分段

    之前一个朋友建议折半分段,但是折半分段只解决了单环形轨迹,如果来个奥运五环的轨迹,又吃不消了,所以考虑网格分段和基于方向角的分段,其实网格分段连环形轨迹的问题都解决不了,所以终极方案还是基于方向角的分段。当然,关于分段还有其他的方法,这里主要用到这两种,而且网格划分不仅仅是用在这里,其他地方也用得到,比如为提取停留事件的聚类做数据准备。

    网格分段

    算法原理
    1、对一组轨迹进行边界检索,获取最小经纬度坐标和最大经纬度坐标;
    2、计算需要划分的网格数量和增长因子;
    3、创建网格;
    4、分配坐标点到网格;
    5、通过网格索引查询网格;

    原理图
     
    类图
     
    网格数量=Math.sqr(轨迹数量) 
    边数量= Math.ceil(Math.sqr(网格数量))
    MeshIndex索引检索算法:二分法(BinarySearch)

    关键代码

        /**
    	 * 二分查找
    	 * 
    	 * @param startIndex
    	 *            开始索引
    	 * @param endIndex
    	 *            结束索引
    	 * @param value
    	 *            经纬度值
    	 * @param arr
    	 *            值数组
    	 * @return 返回所在范围的索引
    	 */
    	private Integer binarySearch(int startIndex, int endIndex, Long value) {
    		if (startIndex > endIndex) {
    			return -1;
    		}
    		count++;
    		if (startIndex == 4 && endIndex == 4) {
    			System.out.println("");
    		}
    		int midIndex = startIndex + (endIndex - startIndex) / 2;
    		midIndex = midIndex < arr.length ? midIndex : arr.length - 1;
    		if (isInBoundary(midIndex, value)) {
    			return midIndex;
    		} else if (isInLeft(midIndex, value)) {
    			return binarySearch(startIndex, midIndex - 1, value);
    		} else {
    			return binarySearch(midIndex + 1, endIndex, value);
    		}
    	}
    

    基于方向角的分段
    算法原理
    有坐标集合 P∈{1,2,3…i}
    遍历集合P 
        初始化方向角度Angle_P1_P2,进入下一次循环
    计算Pi-1到Pi的方向角Angle_Pi-1_Pi
        计算Angle_Pi-1_Pi与Angle_P1_P2的方向角度差
        If(小于15°)
            进入下一次循环
        else
            将初始方向角度小于15的集合P1到Pi-1记录为一个分段
            初始化方向角度Angle_Pi_Pi+1,进入下一次循环

    关键代码

            Map<Integer, List<T>> segMap = new HashMap<>();
    		int startIndex = 0;
    		double startAngleSegment = -1;
    		for (int i = 5; i < points.size(); i++) {
    			int tmpStartIndex = -1;
    			if (i > 4 && i - startIndex > 4) {
    				tmpStartIndex = i - 5;
    			} else {
    				tmpStartIndex = startIndex;
    			}
    			T start = points.get(tmpStartIndex);
    			T cur = points.get(i);
    			double angleSegment = AngleUtil.getAngle(start, cur);
    			// 初始化方向角
    			if (startAngleSegment < 0) {
    				startAngleSegment = angleSegment;
    				continue;
    			}
    			// 计算当前方向角与初始方向角的角度差
    			double δAngle = Math.abs(startAngleSegment - angleSegment);
    			if (δAngle > 15) {
    				segMap.put(i, loadSegments(startIndex, i, points));
    				startIndex = i;
    				startAngleSegment = -1;
    			}
    			if (i == points.size() - 1 && startIndex < points.size() - 1) {
    				segMap.put(i, loadSegments(startIndex, i, points));
    			}
    		}
    

    正北方向角计算公式代码

        /**
    	 * 获取AB连线与正北方向的角度
    	 * 
    	 * @param A
    	 *            A点的经纬度
    	 * @param B
    	 *            B点的经纬度
    	 * @return AB连线与正北方向的角度(0~360)
    	 */
    	public static <T extends AbstractPoint> double getAngle(T point1, T point2) {
    		MyLatLng A = new MyLatLng(point1.getLongitude(), point1.getLatitude());
    		MyLatLng B = new MyLatLng(point2.getLongitude(), point2.getLatitude());
    		double dx = (B.m_RadLo - A.m_RadLo) * A.Ed;
    		double dy = (B.m_RadLa - A.m_RadLa) * A.Ec;
    		double angle = 0.0;
    		angle = Math.atan(Math.abs(dx / dy)) * 180. / Math.PI;
    		double dLo = B.m_Longitude - A.m_Longitude;
    		double dLa = B.m_Latitude - A.m_Latitude;
    		if (dLo > 0 && dLa <= 0) {
    			angle = (90. - angle) + 90;
    		} else if (dLo <= 0 && dLa < 0) {
    			angle = angle + 180.;
    		} else if (dLo < 0 && dLa >= 0) {
    			angle = (90. - angle) + 270;
    		}
    		return angle;
    	}
    

    1.4 插值算法

    插值算法这里用的是flanagan包(Dr Michael Thomas Flanagan)中的三次样条插值算法,代码如下:

    public static <T extends AbstractPoint> Map<Long, Double[]> interpolate(List<T> list) {
    		if (list == null || list.size() < 2) {
    			return null;
    		}
    
    		double[] timespans = new double[list.size()];
    		double[] lngs = new double[list.size()];
    		double[] lats = new double[list.size()];
    		for (int i = 0; i < list.size(); i++) {
    			T t = list.get(i);
    			timespans[i] = t.getTimeLong().doubleValue();
    			lngs[i] = t.getLongitude();
    			lats[i] = t.getLatitude();
    		}
    		CubicSplineFast csLng = new CubicSplineFast(timespans, lngs);
    		CubicSplineFast csLat = new CubicSplineFast(timespans, lats);
    		// 计算需要插值的时间
    		List<Double> needInterpolationTimespans = searchExceptionDuration(list);
    		Map<Long, Double[]> map = new HashMap<>();
    		for (int i = 0; i < needInterpolationTimespans.size(); i++) {
    			Double timespan = needInterpolationTimespans.get(i);
    			double lng = csLng.interpolate(timespan);
    			double lat = csLat.interpolate(timespan);
    			map.put(timespan.longValue(), new Double[] { lng, lat });
    		}
    		return map;
    }
    
    /**
    	 * 查找间隔大于30秒,小于15分钟的节点,以30秒为间隔进行插值
    	 * 
    	 * @param list
    	 * @return 需要插值的时刻点
    	 */
    private static <T extends AbstractPoint> List<Double> searchExceptionDuration(List<T> list) {
    		List<Double> needInterpolation = new ArrayList<>();
    		for (int i = 1; i < list.size(); i++) {
    			T last = list.get(i - 1);
    			T current = list.get(i);
    			Long duration = current.getTimeLong() - last.getTimeLong();
    			if (duration.doubleValue() > MAX_DURATION_THRESHOLD && duration.doubleValue() < EXCEPTION_THRESHOLD) {
    				Double ceil = Math.ceil(duration.doubleValue() / MAX_DURATION_THRESHOLD);
    				// 计算增长因子
    				Double growthFactor = duration.doubleValue() / ceil;
    				for (int j = 1; j < ceil; j++) {
    					double e = last.getTimeLong().doubleValue() + growthFactor * j;
    					System.out.println(e);
    					needInterpolation.add(e);
    				}
    			}
    		}
    		return needInterpolation;
    }
    

    说明:
    1、将时间作为纵轴,经度和纬度分别作为横轴进行系数计算,得到曲线方程;
    2、查询并计算缺失坐标的时刻;
    3、根据曲线方程计算缺失时刻的坐标;

    三、基于权重的地图匹配算法

        匹配算法过程:

        降噪->分段->压缩->附近道路检索->匹配->组合分段

        降噪算法:中值滤波、极值滤波

        分段算法:网格分段、基于方向角的分段

        压缩算法:道格拉斯

        匹配算法:方向、距离、形状相似度结果结合权重的综合计算,理论依据请参考《基于权重的地图匹配算法》,苏海滨,陈永利,刘强

    3.1、计算方向相似度(ω1)

    算法原理

        通过计算候选路段和轨迹的夹角余弦得到相似度结果,该结果越接近1,相似度越高。

     

    步骤如下:

    1、计算候选路段方向与正北方向的夹角θ1

    2、计算轨迹方向与正北方向夹角为θ2

    3、计算θ1θ2角度差Δθ

    4、计算cosΔθ得到夹角余弦结果ω1

     

    关键代码

        /**
    
         * 计算两条线段夹角余弦
    
         * @param start1 线段1的开始坐标
    
         * @param end1 线段1的结束坐标
    
         * @param start2 线段2的开始坐标
    
         * @param end2 线段2的结束坐标
    
         * @return
    
         */
    
        public static <T extends AbstractPoint> double cosθ(T start1, T end1, T start2, T end2) {
    
            // 把两条线段平移到原点(线段开始、结束均减去开始点的坐标)
    
            double x1 = end1.getLatitude() - start1.getLatitude();
    
            double y1 = end1.getLongitude() - start1.getLongitude();
    
           
    
            double x2 = end2.getLatitude() - start2.getLatitude();
    
            double y2 = end2.getLongitude() - start2.getLongitude();
    
           
    
            double xi = Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2));
    
            double yi = Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2));
    
            if (xi == 0 || yi == 0) {
    
                return 0;
    
            }
    
            double cos = (x1 * x2 + y1 * y2) / (xi * yi);
    
            return cos;
    
        }

    3.2、计算距离相似度(ω2)

    算法原理

        计算轨迹点到候选路段的投影总距离totalDistance totalDistance最小的路段则为最近的路段,因为计算规则是距离越小权重越大,所以ω2=1/(1+totalDistance)

    uploading.4e448015.gif转存失败重新上传取消投影距离计算公式(参考《段宗涛,等:一种改进的轨迹地图匹配算法》)

    uploading.4e448015.gif转存失败重新上传取消

    uploading.4e448015.gif转存失败重新上传取消

    关键代码:

    /**
    
         * 计算投影dest点在start和end两点之间的投影 《段宗涛,等:一种改进的轨迹地图匹配算法》
    
         *
    
         * @param start
    
         * @param end
    
         * @param dest
    
         * @return
    
         */
    
        public static <T extends AbstractPoint> Double[] calcProjectionPosition(T start, T end, T dest) {
    
            double k = calcK(start, end);
    
            double doubleK = k * k;
    
            Double[] destPosition = new Double[2];
    
            destPosition[0] = (doubleK * dest.getLongitude() + end.getLongitude() - k * end.getLatitude() + k * dest.getLatitude()) / (doubleK + 1);
    
            destPosition[1] = (doubleK * end.getLatitude() + dest.getLatitude() - k * end.getLongitude() + k * dest.getLongitude()) / (doubleK + 1);
    
            return destPosition;
    
        }

    3.3、计算形状相似度(ω3)

    算法原理

    1. 计算轨迹到候选路段的投影坐标,再计算出这投影坐标的距离da;
    2. 计算轨迹的两点间距离dp;
    3. 计算距离差值Δd=dp-da,Δd越小,形状越相似
    4. 因为计算规则是距离越小权重越大,所以ω3=1/(1+Δd)

    uploading.4e448015.gif转存失败重新上传取消

    关键代码:

    public static <T extends AbstractPoint> double caculatePerpen(List<T> ts, List<RoadPoint> road) {
    
            double total = 0.0D;
    
            for (int i = 1; i < ts.size(); i++) {
    
                T start = ts.get(0);
    
                T end = ts.get(ts.size() - 1);
    
                double distance = DistanceHepler.distance(start, end);
    
                double perpenDistance = caculatePerpen(start, end, road.get(0), road.get(road.size() - 1));
    
                double Δdistance = 1 / (1 + (distance - perpenDistance));
    
                total += Δdistance;
    
            }
    
            return total;
    
        }
    
    
    
    public static <T extends AbstractPoint> double caculatePerpen(T si, T ei, T sj, T ej) {
    
    
    
            double x1 = sj.getLatitude() - si.getLatitude();
    
            double y1 = sj.getLongitude() - si.getLongitude();
    
    
    
            double x2 = ei.getLatitude() - si.getLatitude();
    
            double y2 = ei.getLongitude() - si.getLongitude();
    
    
    
            double x3 = ej.getLatitude() - si.getLatitude();
    
            double y3 = ej.getLongitude() - si.getLongitude();
    
    
    
            double x = Math.pow(x2, 2) + Math.pow(y2, 2);
    
    
    
            double u1 = (x1 * x2 + y1 * y2) / x;
    
            double u2 = (x3 * x2 + y3 * y2) / x;
    
    
    
            double psx = si.getLatitude() + u1 * x2;
    
            double psy = si.getLongitude() + u1 * y2;
    
    
    
            double pex = si.getLatitude() + u2 * x2;
    
            double pey = si.getLongitude() + u2 * y2;
    
    
    
            double Lper1 = Math.sqrt(Math.pow(psx - sj.getLatitude(), 2) + Math.pow(psy - sj.getLongitude(), 2));
    
            double Lper2 = Math.sqrt(Math.pow(pex - ej.getLatitude(), 2) + Math.pow(pey - ej.getLongitude(), 2));
    
            double d_perpen;
    
            if (Lper1 == 0 && Lper2 == 0) {
    
                d_perpen = 0;
    
            } else {
    
                d_perpen = (Math.pow(Lper1, 2) + Math.pow(Lper2, 2)) / (Lper1 + Lper2);
    
            }
    
            return d_perpen;
    
        }

    3.4、计算权重

    权重总值为1,方向、距离、形状三个相似度结果的权重分配如下:

           方向:0.5

           距离:0.3

           形状:0.2

    最终权重计算公式如下:

    ω = 0.5*ω1 + 0.3*ω2 + 0.2*ω3

    计算完成后,对所有候选路段的权重进行倒排,取权重结果最大的候选路段;

     

    关键代码:

    Double[] WEIGHTING_COEFFICIENT = { 0.5D, 0.3D, 0.2D };
    
        WeightResult weightResult = new WeightResult(i);
    
        List<RoadPoint> road = entity.getRoads().get(i);
    
        // 1、计算方向权重
    
        double cosθ = Calculator.cosθ(tracks, road);
    
        weightResult.setTrackRoadθ(cosθ);
    
        double ω1 = WEIGHTING_COEFFICIENT[0] * cosθ;
    
        weightResult.setΩ1(ω1);
    
        // 2、计算距离权重
    
        double totalProjectionDistance = Calculator.calcLineDistance(tracks, road);
    
        weightResult.setTotalProjectionDistance(totalProjectionDistance);
    
        double ω2 = WEIGHTING_COEFFICIENT[1] / (1 + totalProjectionDistance);
    
        weightResult.setΩ2(ω2);
    
        // 3、计算形状权重
    
        double shapeSimilarity = Calculator.caculatePerpen(tracks, road);
    
        weightResult.setShapeSimilarity(shapeSimilarity);
    
        double ω3 = WEIGHTING_COEFFICIENT[2] * shapeSimilarity;
    
        weightResult.setΩ3(ω3);
    
        weightResult.setWeight(ω1 + ω2 + ω3);

     

    展开全文
  • 文章目录目录地图匹配技术概览文章目录前言一、地图匹配概述二、轨迹预处理1.降噪1.1 中值滤波1.2 极值滤波1.3 分段1.4 插值算法三、基于权重的地图匹配算法3.1、计算方向相似度(ω1)3.2、计算距离相似度(ω2)3.3、...

    文章目录

    目录

    地图匹配技术概览

    文章目录

    前言

    一、地图匹配概述

    二、轨迹预处理

    1.降噪

    1.1 中值滤波

    1.2 极值滤波

    1.3 分段

    1.4 插值算法

    三、基于权重的地图匹配算法

    3.1、计算方向相似度(ω1)

    3.2、计算距离相似度(ω2)

    3.3、计算形状相似度(ω3)

    3.4、计算权重

    总结



    前言

    随着生活质量的日益提高,地图相关技术已经渗透到人们生活的各个角落,本文对地图匹配技术,进行简单的概述和实现,为没接触过地图开放的朋友,又想要了解相关技术的提供一个参考信息,内容有误之处,还请大神指点。

    一、地图匹配概述

    由于GPS技术特性原因,定位结果受客观存在的环境因素影响,我们拿到的原始轨迹数据并不是我们在轨迹结果上看到的那么整洁、规范和有序,如果直接把这些点打到地图上,那么我们的行动轨迹,可能看起来就是这样:

    472141f779261c888bd26807bc4ab2c9.png
    4791c2a88d2f1d89e822c7c009ab2d9a.gif

    所以信号也有颗不安分的心,这份轨迹数据让人看起来很灰心,因为勺子里面装了一些不该有的东西。那么我们需要通过一系列的技术手段,来保留我们想要的、看起来合理的轨迹,去掉看起来不合理的数据。

    这一系列的技术手段,包括降噪、分段、抽稀、路网匹配、轨迹补偿等,如下图

    c35ab51466473d683684d7c5539c6330.png
    426d2bc1dcac1e4bbcc80f35fe2cc910.gif

    降噪:降噪技术在数据处理方面应用得非常广泛,例如BI、机器学习等领域,数据几乎都需要进行噪点处理,降噪后的数据通常会存在多多少少的失真,这个缺陷可以通过后期的路网匹配来进行修正;

    抽稀:浮点运算是个比较消耗CPU性能的计算,我们通常需要对原始数据进行抽稀处理,将原始数据精简为足以还原轨迹的数量即可;

    路网匹配:由于信号偏移、降噪处理等因素,导致有些轨迹点是不在道路网上的,当我们把这些点打到地图上以后,会发现我们可能行走在山顶、湖泊、大海,显然这并不合理,所以我们需要结合路网数据,将轨迹拟合到道路网。

    二、轨迹预处理

    1.降噪

    剔除数据中的冗余点和噪音点,通常使用,噪音滤波技术,主要算法包括中值滤波、均值滤波、卡尔曼滤波等;

    轨迹压缩技术,通常使用道格拉斯压缩算法;

    轨迹分段技术,通常使用网格划分算法,以及角度、密度、速度相似度匹配算法

    后续小节将对各个处理节点算法进行一一详解。

    1.1 中值滤波

    当时由于项目时间原因,中值滤波算法是本次主要降噪算法,该算法在当前版本中,实现成本、学习成本、处理效果是最优选择。

    算法原理

    1、对坐标点Pi,获取前后n(n为大于2的偶数)个节点的集合R;
    2、将R的经度、纬度,分别进行正序排序;
    3、分别取经度和纬度的中间值,作为该节点的最终经度和纬度;

    图例:

    ccd0064a995843da9dd9786419876235.png
    d425498c6bda8ceecc87ccb72a209fa7.gif

    关键代码:

    / 起始索引,前面range个坐标不处理int startIndex = STEP_SIZE / 2 + 1;// 结束索引,后range个坐标不处理        int endIndex = tracks.size() - STEP_SIZE / 2;        // STEP_SIZE每次处理的坐标个数,除以二即为前后处理的范围        int range = STEP_SIZE / 2;        for (int i = startIndex; i < endIndex; i++) {            UserTrackDTO track = tracks.get(i);            List lngs = new ArrayList<>();            List lats = new ArrayList<>();            // 获取预定范围间的所有经度和纬度            for (int j = i - range; j <= i + range; j++) {                lngs.add(tracks.get(j).getLngDouble());                lats.add(tracks.get(j).getLatDouble());            }            // 排序            Collections.sort(lngs);            Collections.sort(lats);            // 取中间            track.setLng(String.valueOf(lngs.get(3)));            track.setLat(String.valueOf(lats.get(3)));    }
    78c03e553a480043b006939228700f9d.gif

    中值滤波的缺点:对于连续多个噪点的数据处理得并不理想,增加步长会增加时间复杂度和严重失真,后续会考虑引入卡尔曼滤波算法看看效果;

    1.2 极值滤波

    算法原理
    1、计算各个坐标点距离上一个点的距离、速度;
    2、按比例移除距离、速度较大的点;
    关键代码:

            tracks.get(0).setDistance(0);        for (int i = 1; i < tracks.size(); i++) {            UserTrackDTO lastTrack = tracks.get(i - 1);            UserTrackDTO track = tracks.get(i);            Double distance = DistanceHepler.distance(track, lastTrack);            track.setDistance(distance.intValue());        }        Double maxSize = tracks.size() * 0.80D;        tracks = tracks.stream()                .sorted(Comparator.comparing(UserTrackDTO::getDistance))                .collect(Collectors.toList());        tracks = tracks.stream()                .limit(maxSize.intValue())                .collect(Collectors.toList());        tracks = tracks.stream()                .sorted(Comparator.comparing(UserTrackDTO::getIndex))                .collect(Collectors.toList());
    385baea039ad3c98f17cd1f16385b312.gif

    极值滤波缺点:只能按预设定的阈值进行截取,未考虑当前路况等综合情况进行阈值的设定,会导致精确度不足;
    1.3 压缩

    算法原理
    (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦;
    (2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离d;
    (3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。
    (4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段曲线进行1~3的处理。
    (5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。
    图例:

    82b5936381c4cc1f71e8196038005960.png
    10e19ef5a122f1c1066bb96728a0f3b3.gif

    关键代码:

        /** *  * @param coordinate * @param dMax * @return */public static List douglasPeucker(List coordinate, int dMax) {// 抽稀点数量需要大于2if (coordinate == null || coordinate.size() <= 2) {return coordinate;}coordinate = checkCircle(coordinate);// 起点和终点重合时,分段处理int endIndex = coordinate.size() - 1;List result = new ArrayList<>();compressLine(coordinate, result, 0, endIndex, dMax);result.add(coordinate.get(0));result.add(coordinate.get(endIndex));return result.stream()            .sorted(Comparator.comparing(UserTrackDTO::getIndex))            .collect(Collectors.toList());}/** * 递归方式压缩轨迹 *  * @param coordinate * @param result * @param start * @param end * @param dMax * @return */private static void compressLine(List coordinate, List result, int start, int end, int dMax) {if (start < end) {double maxDist = 0;int currentIndex = 0;UserTrackDTO startPoint = coordinate.get(start);UserTrackDTO endPoint = coordinate.get(end);for (int i = start + 1; i < end; i++) {double currentDist = distToSegment(startPoint, endPoint, coordinate.get(i));if (currentDist > maxDist) {maxDist = currentDist;currentIndex = i;}}if (maxDist >= dMax) {// 将当前点加入到过滤数组中result.add(coordinate.get(currentIndex));// 将原来的线段以当前点为中心拆成两段,分别进行递归处理compressLine(coordinate, result, start, currentIndex, dMax);compressLine(coordinate, result, currentIndex, end, dMax);}}}
    bbf003b5544488a89fb0559353f443f3.gif

    这个算法处理环形轨迹的时候,会将整条轨迹全部精简掉,所以这里用到分段技术。

    1.3 分段

    之前一个朋友建议折半分段,但是折半分段只解决了单环形轨迹,如果来个奥运五环的轨迹,又吃不消了,所以考虑网格分段和基于方向角的分段,其实网格分段连环形轨迹的问题都解决不了,所以终极方案还是基于方向角的分段。当然,关于分段还有其他的方法,这里主要用到这两种,而且网格划分不仅仅是用在这里,其他地方也用得到,比如为提取停留事件的聚类做数据准备。

    网格分段

    算法原理
    1、对一组轨迹进行边界检索,获取最小经纬度坐标和最大经纬度坐标;
    2、计算需要划分的网格数量和增长因子;
    3、创建网格;
    4、分配坐标点到网格;
    5、通过网格索引查询网格;

    原理图

    c999726b05f7af176668fde528dd58d4.png
    0379c2e307cdc7a130e4b8086450244b.gif


    类图

    19b36225cb737296d57f303f8fb189e3.png
    8f50b81a757189d7d7b6ecaed47e0bea.gif


    网格数量=Math.sqr(轨迹数量)
    边数量= Math.ceil(Math.sqr(网格数量))
    MeshIndex索引检索算法:二分法(BinarySearch)

    关键代码

        /** * 二分查找 *  * @param startIndex *            开始索引 * @param endIndex *            结束索引 * @param value *            经纬度值 * @param arr *            值数组 * @return 返回所在范围的索引 */private Integer binarySearch(int startIndex, int endIndex, Long value) {if (startIndex > endIndex) {return -1;}count++;if (startIndex == 4 && endIndex == 4) {System.out.println("");}int midIndex = startIndex + (endIndex - startIndex) / 2;midIndex = midIndex < arr.length ? midIndex : arr.length - 1;if (isInBoundary(midIndex, value)) {return midIndex;} else if (isInLeft(midIndex, value)) {return binarySearch(startIndex, midIndex - 1, value);} else {return binarySearch(midIndex + 1, endIndex, value);}}
    6fcb73206bfa93cde930953b91db7193.gif

    基于方向角的分段
    算法原理
    有坐标集合 P∈{1,2,3…i}
    遍历集合P
    初始化方向角度Angle_P1_P2,进入下一次循环
    计算Pi-1到Pi的方向角Angle_Pi-1_Pi
    计算Angle_Pi-1_Pi与Angle_P1_P2的方向角度差
    If(小于15°)
    进入下一次循环
    else
    将初始方向角度小于15的集合P1到Pi-1记录为一个分段
    初始化方向角度Angle_Pi_Pi+1,进入下一次循环

    关键代码

            Map> segMap = new HashMap<>();int startIndex = 0;double startAngleSegment = -1;for (int i = 5; i < points.size(); i++) {int tmpStartIndex = -1;if (i > 4 && i - startIndex > 4) {tmpStartIndex = i - 5;} else {tmpStartIndex = startIndex;}T start = points.get(tmpStartIndex);T cur = points.get(i);double angleSegment = AngleUtil.getAngle(start, cur);// 初始化方向角if (startAngleSegment < 0) {startAngleSegment = angleSegment;continue;}// 计算当前方向角与初始方向角的角度差double δAngle = Math.abs(startAngleSegment - angleSegment);if (δAngle > 15) {segMap.put(i, loadSegments(startIndex, i, points));startIndex = i;startAngleSegment = -1;}if (i == points.size() - 1 && startIndex < points.size() - 1) {segMap.put(i, loadSegments(startIndex, i, points));}}
    df2ed39b528e0b85e2b86652e1bd1223.gif

    正北方向角计算公式代码

        /** * 获取AB连线与正北方向的角度 *  * @param A *            A点的经纬度 * @param B *            B点的经纬度 * @return AB连线与正北方向的角度(0~360) */public static  double getAngle(T point1, T point2) {MyLatLng A = new MyLatLng(point1.getLongitude(), point1.getLatitude());MyLatLng B = new MyLatLng(point2.getLongitude(), point2.getLatitude());double dx = (B.m_RadLo - A.m_RadLo) * A.Ed;double dy = (B.m_RadLa - A.m_RadLa) * A.Ec;double angle = 0.0;angle = Math.atan(Math.abs(dx / dy)) * 180. / Math.PI;double dLo = B.m_Longitude - A.m_Longitude;double dLa = B.m_Latitude - A.m_Latitude;if (dLo > 0 && dLa <= 0) {angle = (90. - angle) + 90;} else if (dLo <= 0 && dLa < 0) {angle = angle + 180.;} else if (dLo < 0 && dLa >= 0) {angle = (90. - angle) + 270;}return angle;}
    0a9ab65426103cbc2574cc8a5700e4a4.gif

    1.4 插值算法

    插值算法这里用的是flanagan包(Dr Michael Thomas Flanagan)中的三次样条插值算法,代码如下:

    public static  Map interpolate(List list) {if (list == null || list.size() < 2) {return null;}double[] timespans = new double[list.size()];double[] lngs = new double[list.size()];double[] lats = new double[list.size()];for (int i = 0; i < list.size(); i++) {T t = list.get(i);timespans[i] = t.getTimeLong().doubleValue();lngs[i] = t.getLongitude();lats[i] = t.getLatitude();}CubicSplineFast csLng = new CubicSplineFast(timespans, lngs);CubicSplineFast csLat = new CubicSplineFast(timespans, lats);// 计算需要插值的时间List needInterpolationTimespans = searchExceptionDuration(list);Map map = new HashMap<>();for (int i = 0; i < needInterpolationTimespans.size(); i++) {Double timespan = needInterpolationTimespans.get(i);double lng = csLng.interpolate(timespan);double lat = csLat.interpolate(timespan);map.put(timespan.longValue(), new Double[] { lng, lat });}return map;}/** * 查找间隔大于30秒,小于15分钟的节点,以30秒为间隔进行插值 *  * @param list * @return 需要插值的时刻点 */private static  List searchExceptionDuration(List list) {List needInterpolation = new ArrayList<>();for (int i = 1; i < list.size(); i++) {T last = list.get(i - 1);T current = list.get(i);Long duration = current.getTimeLong() - last.getTimeLong();if (duration.doubleValue() > MAX_DURATION_THRESHOLD && duration.doubleValue() < EXCEPTION_THRESHOLD) {Double ceil = Math.ceil(duration.doubleValue() / MAX_DURATION_THRESHOLD);// 计算增长因子Double growthFactor = duration.doubleValue() / ceil;for (int j = 1; j < ceil; j++) {double e = last.getTimeLong().doubleValue() + growthFactor * j;System.out.println(e);needInterpolation.add(e);}}}return needInterpolation;}
    e9e6ab6ae108a49053510cdea711f22c.gif

    说明:
    1、将时间作为纵轴,经度和纬度分别作为横轴进行系数计算,得到曲线方程;
    2、查询并计算缺失坐标的时刻;
    3、根据曲线方程计算缺失时刻的坐标;

    三、基于权重的地图匹配算法

    匹配算法过程:

    降噪->分段->压缩->附近道路检索->匹配->组合分段

    降噪算法:中值滤波、极值滤波

    分段算法:网格分段、基于方向角的分段

    压缩算法:道格拉斯

    匹配算法:方向、距离、形状相似度结果结合权重的综合计算,理论依据请参考《基于权重的地图匹配算法》,苏海滨,陈永利,刘强

    3.1、计算方向相似度(ω1)

    算法原理

    通过计算候选路段和轨迹的夹角余弦得到相似度结果,该结果越接近1,相似度越高。

    a7dd201a3255067e5045025f920e7e4e.png
    b225710ac10898055feaeb50cbb2c9e7.gif

    步骤如下:

    1、计算候选路段方向与正北方向的夹角θ1;

    2、计算轨迹方向与正北方向夹角为θ2;

    3、计算θ1和θ2角度差Δθ;

    4、计算cosΔθ得到夹角余弦结果ω1;

    关键代码

        /**     * 计算两条线段夹角余弦     * @param start1 线段1的开始坐标     * @param end1 线段1的结束坐标     * @param start2 线段2的开始坐标     * @param end2 线段2的结束坐标     * @return     */    public static  double cosθ(T start1, T end1, T start2, T end2) {        // 把两条线段平移到原点(线段开始、结束均减去开始点的坐标)        double x1 = end1.getLatitude() - start1.getLatitude();        double y1 = end1.getLongitude() - start1.getLongitude();               double x2 = end2.getLatitude() - start2.getLatitude();        double y2 = end2.getLongitude() - start2.getLongitude();               double xi = Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2));        double yi = Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2));        if (xi == 0 || yi == 0) {            return 0;        }        double cos = (x1 * x2 + y1 * y2) / (xi * yi);        return cos;    }
    f1d902160152b760ddbe58e59805ab94.gif

    3.2、计算距离相似度(ω2)

    算法原理

    计算轨迹点到候选路段的投影总距离totalDistance, totalDistance最小的路段则为最近的路段,因为计算规则是距离越小权重越大,所以ω2=1/(1+totalDistance);

    9090db4c502676eadc17f8018385c0c9.png
    a0089f9b4e1f2781fabc6d7f66ce5e78.gif

    7e3be015e4059a3fcb5eb594a3f26611.gif
    7d872b167c14a76778da6e2a05ccec2c.gif

    ​转存失败重新上传取消投影距离计算公式(参考《段宗涛,等:一种改进的轨迹地图匹配算法》)

    30e0c4b2e0d4892b91a1e309cd764659.png
    a777ac1792c7e4b6978ae004783aa07b.gif

    6195ce8c88b055a70f436bd471fff518.png
    d3888e75e27de627ed61669f7150436c.gif

    5c67ebb12b2fd14d2d45638c7805ac72.gif
    02ea46c1334885be578938ab89d70460.gif

    ​转存失败重新上传取消

    5425f8144eb25f6a007a4f9c14381a35.gif
    7568f10d588090261df558330e54bbe0.gif

    ​转存失败重新上传取消

    关键代码:

    /**     * 计算投影dest点在start和end两点之间的投影 《段宗涛,等:一种改进的轨迹地图匹配算法》     *     * @param start     * @param end     * @param dest     * @return     */    public static  Double[] calcProjectionPosition(T start, T end, T dest) {        double k = calcK(start, end);        double doubleK = k * k;        Double[] destPosition = new Double[2];        destPosition[0] = (doubleK * dest.getLongitude() + end.getLongitude() - k * end.getLatitude() + k * dest.getLatitude()) / (doubleK + 1);        destPosition[1] = (doubleK * end.getLatitude() + dest.getLatitude() - k * end.getLongitude() + k * dest.getLongitude()) / (doubleK + 1);        return destPosition;    }
    21ad5cfb1af02ce5b0e01940acae3513.gif

    3.3、计算形状相似度(ω3)

    算法原理

    1. 计算轨迹到候选路段的投影坐标,再计算出这投影坐标的距离da;
    2. 计算轨迹的两点间距离dp;
    3. 计算距离差值Δd=dp-da,Δd越小,形状越相似
    4. 因为计算规则是距离越小权重越大,所以ω3=1/(1+∑Δd);
    3bf83e5a86ce5325346be4eb069ea00e.png
    859f35fd2b7a4f89d0d6227bda37beea.gif

    335539c9c40f28c716a57b5eaec97c75.gif
    1ecfab6671443944eb1b5154b860e029.gif

    ​转存失败重新上传取消

    关键代码:

    public static  double caculatePerpen(List ts, List road) {        double total = 0.0D;        for (int i = 1; i < ts.size(); i++) {            T start = ts.get(0);            T end = ts.get(ts.size() - 1);            double distance = DistanceHepler.distance(start, end);            double perpenDistance = caculatePerpen(start, end, road.get(0), road.get(road.size() - 1));            double Δdistance = 1 / (1 + (distance - perpenDistance));            total += Δdistance;        }        return total;    }public static  double caculatePerpen(T si, T ei, T sj, T ej) {        double x1 = sj.getLatitude() - si.getLatitude();        double y1 = sj.getLongitude() - si.getLongitude();        double x2 = ei.getLatitude() - si.getLatitude();        double y2 = ei.getLongitude() - si.getLongitude();        double x3 = ej.getLatitude() - si.getLatitude();        double y3 = ej.getLongitude() - si.getLongitude();        double x = Math.pow(x2, 2) + Math.pow(y2, 2);        double u1 = (x1 * x2 + y1 * y2) / x;        double u2 = (x3 * x2 + y3 * y2) / x;        double psx = si.getLatitude() + u1 * x2;        double psy = si.getLongitude() + u1 * y2;        double pex = si.getLatitude() + u2 * x2;        double pey = si.getLongitude() + u2 * y2;        double Lper1 = Math.sqrt(Math.pow(psx - sj.getLatitude(), 2) + Math.pow(psy - sj.getLongitude(), 2));        double Lper2 = Math.sqrt(Math.pow(pex - ej.getLatitude(), 2) + Math.pow(pey - ej.getLongitude(), 2));        double d_perpen;        if (Lper1 == 0 && Lper2 == 0) {            d_perpen = 0;        } else {            d_perpen = (Math.pow(Lper1, 2) + Math.pow(Lper2, 2)) / (Lper1 + Lper2);        }        return d_perpen;    }
    44031f2794f59d237e6c6f6c14f39845.gif

    3.4、计算权重

    权重总值为1,方向、距离、形状三个相似度结果的权重分配如下:

    方向:0.5

    距离:0.3

    形状:0.2

    最终权重计算公式如下:

    ω = 0.5*ω1 + 0.3*ω2 + 0.2*ω3

    计算完成后,对所有候选路段的权重进行倒排,取权重结果最大的候选路段;

    关键代码:

    Double[] WEIGHTING_COEFFICIENT = { 0.5D, 0.3D, 0.2D };    WeightResult weightResult = new WeightResult(i);    List road = entity.getRoads().get(i);    // 1、计算方向权重    double cosθ = Calculator.cosθ(tracks, road);    weightResult.setTrackRoadθ(cosθ);    double ω1 = WEIGHTING_COEFFICIENT[0] * cosθ;    weightResult.setΩ1(ω1);    // 2、计算距离权重    double totalProjectionDistance = Calculator.calcLineDistance(tracks, road);    weightResult.setTotalProjectionDistance(totalProjectionDistance);    double ω2 = WEIGHTING_COEFFICIENT[1] / (1 + totalProjectionDistance);    weightResult.setΩ2(ω2);    // 3、计算形状权重    double shapeSimilarity = Calculator.caculatePerpen(tracks, road);    weightResult.setShapeSimilarity(shapeSimilarity);    double ω3 = WEIGHTING_COEFFICIENT[2] * shapeSimilarity;    weightResult.setΩ3(ω3);    weightResult.setWeight(ω1 + ω2 + ω3);
    2e8a511fcfe96492acc92e7c905b6cb9.gif
    展开全文
  • 针对基于无线定位的交通信息采集中地图匹配问题,提出一种新的地图匹配算法,算法提取连续多个位置点的瞬时位置、方向和相邻时刻的运动距离构成具有三个特征变量的子时间序列,并用DTW来进行车行轨迹与候选路段的...
  • 提出了在不协调覆盖决策系统下基于扩展分体思想的分辨矩阵以及相关基本知识,给出其相对应的属性约简算法及其解释分析,与其他基于分辨矩阵的算法进行比较,分析了该方法的优越性和实用价值。
  • 基于TDOA定位如何消除或减少沿道路方向上的误差 求帮忙求帮忙
  • 0引 言 随着城市化的进展和汽车的普及,交通拥挤...交通系统是复杂的大系统,我们应从系统论的观点出发,把车辆和道路综合起来考虑,运用各种高新技术系统解决交通问题,智能交通系统(intelligent transport syst...

      0引 言
      随着城市化的进展和汽车的普及,交通拥挤加剧,交通事故频发,交通环境恶化,这成为长期以来困扰发展中国家和发达国家的严重问题。解决此问题的直接方法是提高路网的通行能力。可修建公路的空间有限,而且建设资金筹措困难。交通系统是复杂的大系统,我们应从系统论的观点出发,把车辆和道路综合起来考虑,运用各种高新技术系统解决交通问题,智能交通系统(intelligent transport system)应运而生。
      整个智能交通系统都以车辆的定位导航为核心,车辆导航系统是智能交通系统的中心部件,是其他各种功能应用的基础。GPS或者GPS/INS或者GPS/DR方案以其结构简单、成本低廉、中高精度和良好的动态性能等优点,被广泛的应用于车辆导航系统。本文就是实现组合定位,在应用地图匹配(map matching,MM)定位技术进行车辆定位,以便在行驶过程中为用户提供准确可靠的实时定位信息,为智能交通管理系统的实现提供技术上的保障。
      1地图匹配的原理
      地图匹配是一种基于软件技术的定位修正方法,其基本思想是将车辆定位轨迹与数字地图中的道路网信息联系起来,并由此相对于地图确定车辆的位置。
      地图匹配应用是基于以下2个假设条件:
    (1)车辆总是行驶在道路上;
    (2)采用的道路数据精度要高于车载定位导航系统的定位精度。当上述条件满足时,就可以把定位数据和车辆运行轨迹同数字化地图所提供的道路位置信息相比较,通过适当的匹配过程确定出车辆最可能的行驶路段以及车辆在该路段中的最大可能位置。如果上述假设不成立,则地图匹配将产生错误的位置输出,并可能导致系统性能的严重下降。一般认为用于匹配的数字地图误差不应超过巧米(真实地面距离)。由于陆地车辆在除进入停车场等之外的绝大多数时间内都位于公路网络中,因此使用地图匹配技术的条件是满足的。
      2地图匹配算法
      地图匹配的算法是曲线匹配原理和地理空间接近性分析方法的融合。曲线匹配算法的基本思想是:如果对一条曲线做任意数量、任意比例的分割,分割点都落在另一条曲线上,则两条曲线严格匹配。实际应用中,就是计算一条曲线上相对均匀的某一数量分割点到参考曲线的距离的平均值,将其作为到参考曲线的平均距离,并将此平均距离的倒数作为匹配优劣的度量。空间接近性分析方法就是在已知的可能正确的地理数据集中,按照空间最接近的方法匹配当前定位数据。
      地图匹配算法可分为2个相对独立的过程:一是寻找车辆当前行驶的道路;二是将当前定位点投影到车辆行驶的道路上。其基本办法是按照曲线匹配的思想在车辆航迹的邻近区内搜索所有道路路段及其组合,把这些组合路线分别与车辆航迹求取匹配度量值,将取得最佳匹配度量值的组合路线作为车辆当前行驶路线。地图匹配的常用算法有以下几种:直接投影算法;相关性算法;半确定性算法;概率统计算法;模糊逻辑算法;基于计算几何(非数值计算)知识(并暂时不考虑测量误差)算法。
      由于计算几何知识算法不需要数据融合,极少需要考虑行车方向,非常直观,并且减少了许多数值计算,具有极高的正确匹配率,能够满足快速、准确、实时地定位车辆位置的要求。因此,本系统选用基于计算几何知识的地图匹配算法。
      基于计算几何(非数值计算)知识(并暂不考虑测量误差),根据测量点位坐标有2种思路:
      (1)不断判断刚测得的点位于道路的哪一侧,如果刚测得的点与前期测得的某个点位于道路1的两侧,则车辆在道路1上行驶。如果道路1是一条弯曲的路径,那么经多次测量,并应用该方法也可以判断车辆所处的道路。
      (2)逐段计算测量点集的凸壳,依据道路与凸壳的交判断车辆在哪条道路上行驶。
      但当测量点全部位于1的同一侧时,算法失败。另该算法没有考虑测量误差,由此对GPS测量误差的抗噪性差很有可能使算法失败。
      3改进的地图匹配方法
      在算法设计时基于以下4个方面的考虑:一是效率,地图匹配算法必须能够满足车辆导航实时、快速的要求;二是精度,地图匹配的目的就是有效地提高车辆定位目标的精度,并保持定位结果的稳定性;三是不同交通状况分别给出策略处理以提高道路选取得正确率和缩短匹配时间;四是程序设计,必须用可以量化的方式保证程序设计的可能性。基于上述考虑提出了以下的地图匹配算法,算法分为3个步骤。
      3.1数据预处理过程
      利用各种规则形成的知识库过滤掉异常定位数据,并对其进行有效插值。主要考虑的因素有:GPS板提供的PDOP值(一般取PROP>6)、地图范围(预先确定车辆行驶的有效地理区域),以及车辆的行驶速度等。其规则如下:
    规则1 IF PDOP>6 THEN GPS数据异常,转规则5;
    规则2 IF Pos(L,B)NOT IN MapArea THENGPS数据异常,转规则5;
    规则3 IF Pos( V)>Const Car Speed THENGPS数据异常,转规则5;
    规则4 IF Pos(V)<Const Car Speed(设定Const=8 km/h)THEN GPS数据异常,转规则5;
    规则5 IF Car In隧道或立交桥THEN GPS数据异常;ELSE DR子系统启动获取定位数据。

      其中,MapArea为预先设定的车辆行驶的地理区域理论范围;Pos(L,B)为当前车载GPS定位数据;Pos(V)为当前车辆行驶速度;Car Speed为预先设定的车辆行驶的最大理论值。
      3.2车辆行驶路段的确定
      美国取消SA干涉政策后,GPS的精度在正常状况下小于25 m,在大部分路段可以直接投影获得当前车辆行驶的道路。难于判断的情况一般出现在车辆通视条件较差等原因引起的GPS定位精度降低或车辆在道路交叉口时。
      令△Cdistance为GPS值与当前道路投影点之间的距离;△distance为GPS值与其他道路投影点之间的距离;MaxD为预先设定的搜索道路的距离阈值。阈值通常根据概率准则来确定,即必须以一定的概率包含车辆的实际位置。按照统计理论,可首先确定一个误差椭圆:

      车辆行驶路段的确定规则如下:
      规则1 当接收到电子地图的标定信息如路径规划好的行车路线或者用户自定义道路属性类型代码时,直接利用标定信息匹配到所规划的道路路段上去;
      规则2 IF在一定阈值内搜索到的道路数<1THEN车辆不在道路上,利用概率统计算法,可根据GPS的实时定位数据建立一个动态可调的点缓冲区替代误差椭圆,并利用误差椭圆扩展因子的原理,设置缓冲区扩展比例因子,动态可调的缓冲区半径按30 m,60 m,90 m和120 m四个等级由小到大逐级搜索落入缓冲区内的道路路段。在GPS定位失效的情况下,必须用DR(航位推算)定位的误差参数来代替GPS参数,完成误差区域的定义,以保证匹配过程的连续性。此时,要注意由于DR推算具有误差累积效应,随着推算过程的进行,统计模型误差、测量误差和各种随机误差将会不断累积。因此,在按DR定位的误差参数定义误差椭圆后,还应乘上适当的扩展因子来扩大误差区域,以反映误差累积对定位精度的影响。采用裁剪算法迅速判定侯选路段,通过计算不仅可以判知落入缓冲区内的路段,还可以求得路段与缓冲区的交点,从而取得GPS定位数据的匹配点坐标;
      规则3 IF在一定阈值内搜索到的道路数=1THEN利用直接投影算法,把此道路作为车辆行驶的当前道路;
      规则4 在一定阈值内搜索到的道路数>1&&相同的道路节点号THEN车辆行驶在道路交叉口,根据交通状况种别A,B,C,D划分,采取对应策略,并利用相关性算法,计算测出轨迹与1组地图数据的相关性系数,在所有候选地图路线中与实际测出路线相关性最高的路线即为车辆行驶的真实路线;
      规则5 在一定阈值内搜索到的道路数>1&&不同的道路节点号THEN车辆行驶在距离较近的平行道路之间,采用模糊逻辑算法中的利用距离和方向要素的线性组合方法,改进算法,令p1+p2=1,并对p2参照模糊逻辑算法模式中的确定相似性度量函数的加权因子Q的模糊判决规则确定其值,然后计算基于曲线拟合的地图匹配算法的相似性度量函数s,并选取最小值作为待匹配路段,即:在考虑角度和距离因素的情况下,该路段达到最优。
      加权因子q取值如下:
    规则5.1 IF道路为禁行或禁止转向或单行道的逆向THEN q="1".5*q;
    规则5.2 IF已有路径规划且是路径规划路段THEN q="0".5*q;
    规则5.3 IF道路与车辆的行驶方向一致THEN q="0".25*q。
    规则6 IF发现如离开道路、电子地图简化后较为低级的道路描述不够详细、车辆进入停车场等情况,找不到可以匹配的行走路段THEN手动停止地图匹配,用接收的原始数据直接显示,不进行误差矫正。
      3.3基于模糊逻辑的匹配路段可信度评判
      以候选路段取向与车辆行驶方向的差(△heading,单位:度)值为论域X,令μhh(X)、μhc(x)为取向差(单位:度)的值x隶属于模糊子集"路段与车辆行驶取向一致性好"和"路段与车辆行驶取向一致性差"的隶属度,则μhh(X)、μhc(X)可取为:
     


      在初始位置给定时,利用DR推算能够准确地描述出车辆在短时间内的行驶轨迹。因此,可按如下方式定义候选路段形状与当前车辆行驶轨迹的相似度:根据DR推算原理,现时刻tn的车辆位置(xn,yn)和车辆行驶取向θn可根据上一时刻tn-1的车辆位置(xn-1,yn-1)和行驶取向θn-1按下列公式推出:

      式中:dn-1,n是tn-1到tn时刻车辆行驶过的距离,ωn-1,n是tn-1到tn时刻车辆行驶取向的变化量 (dn-1,n和ωn-1,n均由车载位移传感器和角速度传感器提供)。取车辆当前定位位置p0(x,y)在候选路段上的投影点p′0(x′,y′)为tn时刻DR推算定位的参考位置,取候选路段取向为tn时刻的参考行驶取向,则由DR推算公式可反推出前一时刻的推算定位参考点。通过多次推算即可获得一组参考点,具体数量可根据实际应用的要求确定。这里取参考点数目为5,则可定义候选路段与前5个单位时间内的DR定位轨迹平均距离差(单位:m)为:
     

      上述隶属函数的图形如图1和图2所示。

    以上述隶属度函数为基础,就可以对候选路段是当前车辆所在路段的可能性做出综合评判。以该可能性作为论域U,其元素u与论域X,Y和Z的笛卡尔乘积集:
      它的元素(x,y,z)相对应,即u与三个因素有关。因此,在对u进行模糊评判时,因素集可以取为E={X,Y,Z),评语集可取为F={大,小),综合评判按下面的步骤进行:
      (1) 对u进行单因素评价,然后利用其结果构造表示E与F之间模糊关系的模糊矩阵。设对因素X,Y,Z的单因素评价结果分别为模糊向量R1= [μhh(x),μhc(x)],R2=[μdh(y),μdc(y)]和R3=[μ△dh(z),μ△dc(z)],则将以上模糊向量合在一起便得到表示E与F之间模糊关系的模糊矩阵 
      (2)确定权向量P=[p1,p2,p3],其中p1,p2,p3分别表示因素x,y,z在乱中的重要程度,p1+p2+p3=1。
      (3)作模糊变换Q=P°R,所得模糊向量Q就是被评判对象U在评语集合F上的评判结果,其2个分量表示候选路段是车辆所在路段的可能性大小的程度。
      在以上综合评判算法中,模糊矩阵乘法"°"采用简单的加权平均型算子(⊕,×)以便使结果兼顾各种因素。由于权向量的分量之和为1,运算⊕退化为一般的实数加法,因此算子(⊕,×)也可以改写成(+,×)。在这种情况下,模糊矩阵的乘法与普通矩阵的乘法完全一样。
      有了对候选路段是当前车辆行驶路段的可能性的评价,就可以对以候选路段位置为参考进行地图匹配修正后的定位结果的可信度做出评价。评判中,应考虑到候选路段与前一时刻匹配路段的连通性,为此再引入以下规则:如果候选路段就是前一时刻匹配路段或者与前一时刻的匹配路段相连通,则利用该候选路段修正定位结果的可信度高。以修正结果为评判对象,取评判指标矩阵为(Q,Q′),其中Q是候选路段的可能性评价矩阵,Q′是连通性评价矩阵,当候选路段与前一时刻匹配路段有连通关系时,Q′取为前一时刻匹配路段的可能性评价矩阵,否则以0矩阵取代。取评判权向量为P′=[p′1,p′2,p′3,p′4],其分量分别对应于Q和Q′的各个分量,且p′1+p′2+p′3+p′4=1。将指标矩阵与权向量相乘,得μ=p′°[Q,Q′]T,称μ是修正定位结果的可信度,它为挑选最佳匹配路段提供了明确的依据。
      4实验结果
      交叉路口是地图匹配过程中最易出错的地方根据本文提出的改进的地图匹配算法理论,就交叉路口问题做性能分析,下面分两种情况讨论。
      第一种情况:车辆直行通过交叉路口,如图3所示。


         轨迹点4,5靠近路段1,但轨迹点1、2、3、4、5拟合所得直线远远偏离路段1,靠近路段2,因而轨迹点5会正确匹配到路段2,不会被错误地匹配到路段 1。同理,轨迹点4也正确地匹配到路段2。由于考虑了轨迹的连续性,和基于位置点直接投影算法比起来,本文的算法不容易在交叉点出现匹配错误的情形。
      第二种情况:车辆拐弯通过交叉路口,如图4所示。

      轨迹点1、2、3、4、5拟合得到的拟合直线1与路段2的夹角小于30度,点5被匹配到路段2。同理,2、3、4、5、6拟合得到的拟合直线2与路段2的夹角也小于30度,点6被匹配到路段2。从图上可以看出,点5、6、7、8、9拟合得到的拟合直线5与路段1、2的夹角都大于30度,由算法基本原理可知,9不符合匹配条件,不予匹配。按照同样方法对其他点一一进行匹配。尽管在交叉路口附近会有少数的轨迹点不能被匹配,但匹配出来的轨迹能反映车辆的实际行驶轨迹,较好地处理了交叉路口的地图匹配问题。
      为验证文中提出的地图匹配算法对导航系统定位精度的影响,利用该算法对跑车实测数据进行了实验。匹配结果表明,绝大多数(>96%)定位数据都能相对准确地匹配到道路上,匹配后的定位精度得到提高;匹配算法实现了实时,能够满足实际需要(1次/s);在GPS受到一定程度的遮挡时系统能够正常识别并且匹配。
    (本文转自电子工程世界:http://www.eeworld.com.cn/qcdz/2008/1225/article_624.html)

    转载于:https://www.cnblogs.com/wangzihao/archive/2011/05/05/2037462.html

    展开全文
  • 主要是有关地理信息系统地图面实体匹配技术的资料!
  • 地图匹配相关的几个技术点与地图匹配相关的几个技术点GPS数据采集Matlab mobileGPS独立硬件二者对比:GPS坐标转换GPS数据的可视化交通路网路网格式转换准备文件执行生成sql的命令。路网搜索优化地图匹配中的参数...

    与地图匹配相关的几个技术点

    自从发布若谷:Matlab算法案例— 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching) 之后,不少乎友对此很感兴趣,并联系我,需要付费索求源代码,以供学习、毕业设计使用。
    奈何在提供源代码后,依旧对一些细节,不甚清楚。本文试图总结,与地图匹配相关的几个个问题,供大家借鉴。

    GPS数据采集

    两种方式:

    Matlab mobile

    Matlab有个手机版,可以获取移动轨迹(经纬度)信息,并且格式以.mat格式存储,且匹配Matlab相关函数。

    GPS独立硬件

    本文采用带串口的GPS硬件,用来读取GPS实时采集的信息。 精度可能更高,取决于你的GPS硬件。比如,本文所示案例,其GPS硬件,精确到经纬度的秒,因此精度在15米以内。
    在这里插入图片描述
    关于GPS硬件数据采集,特别注意gPS的协议。详细解析方式,详见之前的知乎博文。

    二者对比:

    便捷性:Matlab mobile当然很方便,硬件成本为零。但是数据格式,主要支持Maltab。若需要转换数据格式,需要在Matlab中,进行数据读取。
    数据精度:GPS独立硬件,数据精度更高,尤其是时间与位置的匹配上,由此产生的实时移动速度,也是精确的。在无遮挡的空旷地段,精度可以达到3米以内。比手机精度,要高。但是,在隧道等地段,手机端能获取数据,尽管数据不是精密测量的,很可能是通过手机自身的惯导和隧道内的通信技术,推算的结果。

    GPS坐标转换

    GPS坐标转换,主要是从经纬度转xyz坐标。 不用多说,直接上程序。见下方:

    function  [x,y,utmzone] = deg2utm(Lat,Lon)
    % -------------------------------------------------------------------------
    % [x,y,utmzone] = deg2utm(Lat,Lon)
    %
    % Description: Function to convert lat/lon vectors into UTM coordinates (WGS84).
    % Some code has been extracted from UTM.m function by Gabriel Ruiz Martinez.
    %
    % Inputs:
    %    Lat: Latitude vector.   Degrees.  +ddd.ddddd  WGS84
    %    Lon: Longitude vector.  Degrees.  +ddd.ddddd  WGS84
    %
    % Outputs:
    %    x, y , utmzone.   See example
    %
    % Example 1:
    %    Lat=[40.3154333; 46.283900; 37.577833; 28.645650; 38.855550; 25.061783];
    %    Lon=[-3.4857166; 7.8012333; -119.95525; -17.759533; -94.7990166; 121.640266];
    %    [x,y,utmzone] = deg2utm(Lat,Lon);
    %    fprintf('%7.0f ',x)
    %       458731  407653  239027  230253  343898  362850
    %    fprintf('%7.0f ',y)
    %      4462881 5126290 4163083 3171843 4302285 2772478
    %    utmzone =
    %       30 T
    %       32 T
    %       11 S
    %       28 R
    %       15 S
    %       51 R
    %
    % Example 2: If you have Lat/Lon coordinates in Degrees, Minutes and Seconds
    %    LatDMS=[40 18 55.56; 46 17 2.04];
    %    LonDMS=[-3 29  8.58;  7 48 4.44];
    %    Lat=dms2deg(mat2dms(LatDMS)); %convert into degrees
    %    Lon=dms2deg(mat2dms(LonDMS)); %convert into degrees
    %    [x,y,utmzone] = deg2utm(Lat,Lon)
    %
    % Author: 
    %   Rafael Palacios
    %   Universidad Pontificia Comillas
    %   Madrid, Spain
    % Version: Apr/06, Jun/06, Aug/06, Aug/06
    % Aug/06: fixed a problem (found by Rodolphe Dewarrat) related to southern 
    %    hemisphere coordinates. 
    % Aug/06: corrected m-Lint warnings
    %-------------------------------------------------------------------------
    
    % Argument checking
    %
    error(nargchk(2, 2, nargin));  %2 arguments required
    n1=length(Lat);
    n2=length(Lon);
    if (n1~=n2)
       error('Lat and Lon vectors should have the same length');
    end
    
    
    % Memory pre-allocation
    %
    x=zeros(n1,1);
    y=zeros(n1,1);
    utmzone(n1,:)='60 X';
    
    % Main Loop
    %
    for i=1:n1
       la=Lat(i);
       lo=Lon(i);
    
       sa = 6378137.000000 ; sb = 6356752.314245;
             
       %e = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sa;
       e2 = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sb;
       e2cuadrada = e2 ^ 2;
       c = ( sa ^ 2 ) / sb;
       %alpha = ( sa - sb ) / sa;             %f
       %ablandamiento = 1 / alpha;   % 1/f
    
       lat = la * ( pi / 180 );
       lon = lo * ( pi / 180 );
    
       Huso = fix( ( lo / 6 ) + 31);
       S = ( ( Huso * 6 ) - 183 );
       deltaS = lon - ( S * ( pi / 180 ) );
    
       if (la<-72), Letra='C';
       elseif (la<-64), Letra='D';
       elseif (la<-56), Letra='E';
       elseif (la<-48), Letra='F';
       elseif (la<-40), Letra='G';
       elseif (la<-32), Letra='H';
       elseif (la<-24), Letra='J';
       elseif (la<-16), Letra='K';
       elseif (la<-8), Letra='L';
       elseif (la<0), Letra='M';
       elseif (la<8), Letra='N';
       elseif (la<16), Letra='P';
       elseif (la<24), Letra='Q';
       elseif (la<32), Letra='R';
       elseif (la<40), Letra='S';
       elseif (la<48), Letra='T';
       elseif (la<56), Letra='U';
       elseif (la<64), Letra='V';
       elseif (la<72), Letra='W';
       else Letra='X';
       end
    
       a = cos(lat) * sin(deltaS);
       epsilon = 0.5 * log( ( 1 +  a) / ( 1 - a ) );
       nu = atan( tan(lat) / cos(deltaS) ) - lat;
       v = ( c / ( ( 1 + ( e2cuadrada * ( cos(lat) ) ^ 2 ) ) ) ^ 0.5 ) * 0.9996;
       ta = ( e2cuadrada / 2 ) * epsilon ^ 2 * ( cos(lat) ) ^ 2;
       a1 = sin( 2 * lat );
       a2 = a1 * ( cos(lat) ) ^ 2;
       j2 = lat + ( a1 / 2 );
       j4 = ( ( 3 * j2 ) + a2 ) / 4;
       j6 = ( ( 5 * j4 ) + ( a2 * ( cos(lat) ) ^ 2) ) / 3;
       alfa = ( 3 / 4 ) * e2cuadrada;
       beta = ( 5 / 3 ) * alfa ^ 2;
       gama = ( 35 / 27 ) * alfa ^ 3;
       Bm = 0.9996 * c * ( lat - alfa * j2 + beta * j4 - gama * j6 );
       xx = epsilon * v * ( 1 + ( ta / 3 ) ) + 500000;
       yy = nu * v * ( 1 + ta ) + Bm;
    
       if (yy<0)
           yy=9999999+yy;
       end
    
       x(i)=xx;
       y(i)=yy;
       utmzone(i,:)=sprintf('%02d %c',Huso,Letra);
    end
    

    GPS数据的可视化

    不考虑背景地图的话,GPS数据的可视化,是特别简单的。本文主要考虑带有地图遥感影像的GPS可视化。本文,主要考虑将gps数据,制作成KML文件,在google Earth上,进行可视化显示。
    在这里插入图片描述
    经过地图辅助后,就变得漂亮多了。
    在这里插入图片描述
    以上地图,是基于高德导航地图,进行的数据可视化。高德地图,还提供了动态演示效果的展示。如下图所示:

    交通路网

    交通路网数据,有很多下载渠道。本文选择了最通用的渠道,就是从开源地图Open Street Map上,免费下载。如图,选择地图区域,并且导出。
    在这里插入图片描述

    不过,需要指出的是,OSM(Open Street Map)的地图,格式不一定满足数据处理的要求,往往需要进行格式转换,才能进一步使用。

    路网格式转换

    本文,就是把Open Street Map 转成为SHAPE file格式后,进行地图匹配的。毕竟,shapefile格式的软件基础ArcGIS是最广泛的。
    其中一个工具是ArcMap,进行格式转换。
    在这里插入图片描述

    具体格式转换,详见下方图示中的按钮和命令。
    在这里插入图片描述
    在这里插入图片描述

    转化成shapefile格式之后,还要转成编程语言能便捷操作的,比如存储至关系数据库中。
    有一个比较常用的工具,shp2mysql。 值得推荐,从2009年第一次使用,到现在,陆陆续续地使用着。之前的博客, 也有介绍。
    https://zhuanlan.zhihu.com/p/102120251

    准备文件

    一个shp文件有多个文件组成, .dbf, .sbn, .sbx, .shp, .shx.
    将shp以及shp的相关文件和DOShere文件放在同一目录下。
    在这里插入图片描述

    执行生成sql的命令。

    shp2MySQL shp文件名.shp 表名 数据库名 > 生成的sql文件名.sql
    进入该文件目录,执行下述命令:

    shp2MySQL Line.shp line hmm4mmYuan > line4mm.sql
    

    路网搜索优化

    面对浩如烟海的路网数据,为了优化路网的搜索效率,GIS的空间分析中,常常采用的是四叉树的数据结构,对路网进行分块、分级存储。本文不进行细致说明。有意者,请关注之前的HMM一文,其包含的代码部分,有详细介绍。

    地图匹配中的参数

    基于隐马尔科夫链的地图匹配中,由于要建设5项参数,其中概率转移时,要考虑前后两个点,到线的映射关系,这其中的转移概率,受到线段长度与相邻GPS点的平均距离。

    • 相邻点的最大、最小、平均距离;
    • 道路线的最大、最小、平均长度;
    • 道路线的总数量;

    分享:无人系统行业交流群

    若谷:自动驾驶行业交流群及公约

    自动驾驶技术是实现更高程度的智能生活的技术基础,目前已经广泛应用于无人车/船/机。
    欢迎大家交流无人系统行业的技术发展(工业数据采集,感知(雷达/毫米波/红外),人工智能算法,图像识别,精密控制,建模与仿真)、产业全供应链融合、岗位招聘与人才求职、创新创业与融资扩产、行业羽毛球联谊赛。
    我是无人驾驶辅助系统ADAS企业的开发者,撰写《无人驾驶–视觉·感知·控制》

    展开全文
  • 然而,现有的地图匹配技术不能满足具有大量轨迹数据的应用的不断增长的需求,例如交通流分析和路线规划。为了解决这个问题,我们提出了一种有效的地图匹配算法,称为Passby。我们不会将每个GPS点都匹配,而是将精力...
  • 一种基于被支持度的决策自适应的全局地图匹配算法,刘聪聪,陈恒鑫,地图匹配技术是建设智慧城市潮流中不可或缺的。地图匹配的难度主要取决于路网的密度和GPS点的质量。然而,大多数现有的地图匹配算
  • 图1 地图匹配示意图 二、算法思想 Barefoot 是一个开源的Java项目,它提供了离线/实时地图匹配及空间分析等服务,其中实时地图匹配的实现思路以Goh[2] 提出的算法作为参考。如图2所示,Barefoot提供的实时地图匹配...
  • 随着城市规模的不断扩大和便民业务的发展,行车导航、共享汽车和物流派送等应用已经深入人们日常生活之中。... [3] https://just.urban-computing.cn/  转载请注明:康瑞部落 » JUST技术:基于HMM的实时地图匹配
  • 出租车轨迹点地图匹配研究

    千次阅读 2019-07-16 23:30:28
    关于地图匹配,已经是一门成熟的技术了,但是网上对地图匹配的开源还是比较少。Github上面虽然有很一些地图匹配的开源工具,但是地图匹配涉及到路网数据和出租车轨迹点数据,不容易对现有的代码进行使用。 所以,...
  • 地图匹配算法能有效地提升定位精度,是定位技术不可或缺的一部分。为提高路径匹配正确率,并适应室内定位环境,提出一种基于路径表的室内地图匹配方法,在传统地图匹配方法的基础上建立一个路径表存放候选路径的信息...
  • 影像匹配技术是一门迅速发展的图像处理技术,在图像镶嵌,图像融合,军事侦察等领域有广泛应用。影像匹配就是将图像归一化到统一的坐标系统中去,将两幅图像或者图像与地图进行空间对准,进而将两幅图像拼接在一起,...
  • 浮动车技术是一种新型交通流信息采集技术。以杭州市浮动车中心地图匹配算法开发为例,对地图匹配算法的实现步骤、组成进行了分析,基于MapObects组件技术,给出了部分功能的具体实现方法。
  • 轨迹预处理(地图匹配Map Matching)

    万次阅读 2018-04-09 11:27:25
    地图匹配Map Matching可以按照两个标准分类两类一种是是否使用了额外的信息,另外一种是轨迹中采样的范围。第一种方法可以分为四类:几何、拓扑、概率、先进技术几何:将GPS点匹配到最近的道路。拓扑:使用frechet ...
  • 如果只使用视觉的话,唯一能够对不同方向的地图进行对齐的信息就是十字路口。但这种方式不是十分稳定。能够提供绝对位置的gps的精度在10米左右,又不够用。 视觉建图中,特征点和相机相互耦合,理论上任意两个特征...
  • 针对地图数据存储部分采用基于区域划分的数据水平切分技术与GeoHash编码技术相结合的方式。方案实现了对大规模车辆的实时监控,解决了大规模数据下并发处理的问题。同时与传统方案比较,方案在达成相同性能条件下...
  • 工具下载 原来的图片切片工具,在对图片切片之前,需要制作源图,在源图中进行图片缩放、旋转等操作,这就是顺序法切图。...而且现在使用了新技术,可以处理photoshop打不开的大图,覆盖地图上更大...
  • 地图定位点与所选目标不匹配 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 开发工具与关键技术:Visual Studio 2015 ,Supermap GIS 作者:陈小白 撰写时间:2019年01月20日 ~...
  • 为了让人们便捷地找到合适的拼车伙伴,运用位置云平台的云存储与检索服务,结合Web服务器和数据库技术,设计并实现了智能拼车匹配系统,并开发了基于嵌入式平台的客户端装置。介绍了系统的架构,论述了位置云端存储...
  • 本文重点解决在多源数据下的数据融合,数据融合模式设计,模板匹配技术,以及导航地图数据空间索引技术研究,车载导航地图制作系统开发,设计,最后形成一套半自动化车载导航地图制作系统。论文体系结构如下:首先...
  • 技术地图 - vue-cli

    2019-05-28 22:15:16
    这是一个新开的'实验性'文章系列,如其名‘技术地图’,这个系列计划剖析一些前端开源项目,可能会探讨这些项目的设计和组织、整理他们使用到技术栈。 首先拿vue-cli小试牛刀,再决定后续要不要继续这个系列. 我...
  • 需要用里程计来弥补地图匹配不好的区域。 要有全局地图可以提高里程计的精度。 里程计和全局的结果要能平滑的融合。 结论: 尝试了很多方案后,觉得使用给予ORB-SLAM修改的版本笔记哦好。 修改内容: 把ORB-...
  • 对开关部分的地图匹配技术进行了研究,并对其过程进行了讨论和测试,其准确性可以提高到98.6%。在以上研究的基础上,构建了列车位置系统。测试表明,差模下的定位精度小于3米,可以满足西部低密度线的需求。
  • 随着导航定位、移动互联网等技术的快速发展,手机、车载定位装置等设备都可以进行地理空间数据采集。这些不同类型的地理空间数据往往能反映出某种规律。...地图匹配是时空轨迹数据处理分析中的关键技术,...
  • 用户通过网页登录的方式在客户端软件上进行登录系统,在登录完成后会根据用户权限的不同进行匹配该权限下所对应监控的车辆,在网页界面上显示这些车辆的各类数据信息,同时调用百度地图在网页上实时跟踪经纬度坐标...
  • 随着导航定位、移动互联网等技术的快速...地图匹配是时空轨迹数据处理分析中的关键技术,能够解决将轨迹数据匹配到道路网络的问题,从而基于轨迹点还原真实轨迹。如何能够快速、有效地实现地图匹配,成为轨迹数据分析的

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 210
精华内容 84
关键字:

地图匹配技术