第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > java编程算法出现在窗口_Java实现轨迹压缩算法开放窗口代码编程实例分享

java编程算法出现在窗口_Java实现轨迹压缩算法开放窗口代码编程实例分享

时间:2023-06-16 08:22:55

相关推荐

java编程算法出现在窗口_Java实现轨迹压缩算法开放窗口代码编程实例分享

Java实现轨迹压缩算法开放窗口代码编程实例分享,今天要给各位朋友分享的这篇文章主要介绍了Java编程实现轨迹压缩算法开放窗口实例代码,具有一定的参考价值,有兴趣的朋友来看看吧。

轨迹压缩算法

场景描述

给定一个GPS数据记录文件,每一条记录包含经度和维度两个坐标字段,根据距离阈值压缩记录,将过滤之后的所有记录的经纬度坐标构成一条轨迹

算法描述

这种算法的用处还是相当广泛的。

轨迹压缩算法分为两大类,分别为无损压缩和有损压缩,无损压缩算法主要包括哈夫曼编码,有损压缩算法又分为批处理方式和在线数据压缩方式,其中批处理方式又包括DP(Douglas-Peucker)算法、TD-TR(Top-Down Time-Ratio)算法和Bellman算法,在线数据压缩方式又包括滑动窗口、开放窗口、基于安全区域的方法等。

代码实现:

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Point;

import java.awt.Toolkit;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStreamReader;

import java.io.RandomAccessFile;

import java.text.DecimalFormat;

import java.util.ArrayList;

import java.util.Iterator;

import javax.swing.JFrame;

import javax.swing.JPanel;

public class TrajectoryCom {

public static void main(String[] args) throws Exception{

//阈值定义

double maxDistanceError = 30;

/*

* 文件读取

* */

//存放从文件读取的位置点的信息列表

ArrayList ENPList = new ArrayList();

//源数据文件的地址 建立文件对象

//这里是需要更改的地方 改你源文件的存放地址 记住如果地址中含"\",记得再加一个"\",原因"\"是转义符号

//这里可以写成C:/Users/Administrator/Desktop/11.6/-10-14-GPS.log

File sourceFile = new File("./-10-14-GPS.log");

//调用文件读取函数 读取文件数据

ENPList = getENPointFromFile(sourceFile);

//这里是测试 有没有读到里面 看看列表里的数据个数 交作业的时候记得注释掉

System.out.println(ENPList.size());

/*

* 数据处理

* 方法:开放窗口轨迹压缩法

* */

//存放目标点的集合

ArrayList rePointList = new ArrayList();

rePointList = openWindowTra(ENPList,maxDistanceError);

System.out.println(rePointList.size());

/*

* 写入目标文件

* */

File targetFile = new File("./-10-14-GPSResult.log");

writeTestPointToFile(targetFile,rePointList);

/*

* 压缩率计算

*/

double cpL = (double)rePointList.size() / (double)ENPList.size() * 100;

DecimalFormat df = new DecimalFormat("0.000000");

System.out.println("压缩率:"+ df.format(cpL) + "%");

/*

* 计算平均距离误差

* */

double aveDisErr = getMeanDistError(ENPList,rePointList);

System.out.println(aveDisErr);

/*

* 画线形成对比图

* */

//generateImage(ENPList,rePointList);

}

/*

* 从提供的文件信息里提取位置点

* 并将每个点的坐标数值调用转换函数存到列表里

* 函数返回一个 存放所有位置点 的集合

*/

public static ArrayList getENPointFromFile(File fGPS)throws Exception{

ArrayList pGPSArray = new ArrayList();

if(fGPS.exists()&&fGPS.isFile()){

InputStreamReader read = new InputStreamReader(new FileInputStream(fGPS));

//输入流初始化

BufferedReader bReader = new BufferedReader(read);

//缓存读取初始化

String str;

String[] strGPS;

int i = 0;

while((str = bReader.readLine())!=null){

//每次读一行

strGPS = str.split(" ");

ENPoint p = new ENPoint();

p.id = i;

i++;

p.pe = (dfTodu(strGPS[3]));

p.pn = (dfTodu(strGPS[5]));

pGPSArray.add(p);

}

bReader.close();

}

return pGPSArray;

}

/**

* 函数功能:将原始经纬度坐标数据转换成度

* 获取的经纬度数据为一个字符串

*/

public static double dfTodu(String str){

int indexD = str.indexOf('.');

//获取 . 字符所在的位置

String strM = str.substring(0,indexD-2);

//整数部分

String strN = str.substring(indexD-2);

//小数部分

double d = double.parsedouble(strM)+double.parsedouble(strN)/60;

return d;

}

/*

* 开放窗口方法实现

* 返回一个压缩后的位置列表

* 列表每条数据存放ID、点的坐标

*

* 算法描述:

* 初始点和浮动点计算出投影点,判断投影点及轨迹点的距离与阈值 如果存在距离大于阈值

* 则初始点放入targetList,浮动点向前检索一点作为新的初始点,新的初始点向后检索第二个作为新的浮动点 在此存在判断 即新的初始点位置+1是不是等于列表长度 这里决定了浮动点的选取

* 如此处理至终点

* */

public static ArrayList openWindowTra(ArrayList sourceList,double maxDis){

ArrayList targetList = new ArrayList();

//定义初始点位置 最开始初始点位置为0

int startPoint = 0;

//定义浮动点位置 最开始初始点位置2

int floatPoint = 2;

//定义当前轨迹点位置 最开始初始点位置为1

int nowPoint = 1;

int len = sourceList.size();

//存放所有窗口内的点的信息集合

ArrayList listPoint = new ArrayList();

listPoint.add(sourceList.get(nowPoint));

//浮动点位置决定循环

while(true){

//标志 用来控制判断是否进行窗口内轨迹点更新

Boolean flag = false;

//计算并判断窗口内所有点和投影点的距离是否大于阈值

for (ENPoint point:listPoint){

double disOfTwo = getDistance(sourceList.get(startPoint),sourceList.get(floatPoint),point);

if(disOfTwo >= 30){

flag = true;

break;

}

}

if(flag){

//窗口内点距离都大于阈值

//初始点加到目标列表

targetList.add(sourceList.get(startPoint));

//初始点变化

startPoint = floatPoint - 1;

//浮动点变化

floatPoint += 1;

if(floatPoint >= len){

targetList.add(sourceList.get(floatPoint-1));

break;

}

//窗口内点变化

listPoint.clear();

//System.out.println(listPoint.size());

listPoint.add(sourceList.get(startPoint+1));

} else{

//距离小于阈值的情况

//初始点不变

//当前窗口集合加入当前浮动点

listPoint.add(sourceList.get(floatPoint));

//浮动点后移一位

floatPoint += 1;

//假如浮动点是终点 并且当前窗口点距离都小于阈值 就直接忽略窗口点 直接将终点加入目标点集合

if(floatPoint >= len){

targetList.add(sourceList.get(startPoint));

targetList.add(sourceList.get(floatPoint-1));

break;

}

}

flag = false;

}

return targetList;

}

/*计算投影点到轨迹点的距离

* 入口是初始点A、浮动点B、当前轨迹点C

* 三角形面积公式

*/

public static double getDistance(ENPoint A,ENPoint B,ENPoint C){

double distance = 0;

double a = Math.abs(geoDist(A,B));

double b = Math.abs(geoDist(B,C));

double c = Math.abs(geoDist(A,C));

double p = (a + b + c)/2.0;

double s = Math.sqrt(p * (p-a) * (p-b) * (p-c));

distance = s * 2.0 / a;

return distance;

}

/*

* ArrayList 拷贝函数

* */

/*提供的函数

* 其中计算距离的函数 经过改造得到下面的距离计算方法

* 具体是怎么计算距离的 我也没研究了

* */

public static double geoDist(ENPoint pA,ENPoint pB){

double radLat1 = Rad(pA.pn);

double radLat2 = Rad(pB.pn);

double delta_lon = Rad(pB.pe - pA.pe);

double top_1 = Math.cos(radLat2) * Math.sin(delta_lon);

double top_2 = Math.cos(radLat1) * Math.sin(radLat2) - Math.sin(radLat1) * Math.cos(radLat2) * Math.cos(delta_lon);

double top = Math.sqrt(top_1 * top_1 + top_2 * top_2);

double bottom = Math.sin(radLat1) * Math.sin(radLat2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.cos(delta_lon);

double delta_sigma = Math.atan2(top, bottom);

double distance = delta_sigma * 6378137.0;

return distance;

}

public static double Rad(double d){

return d * Math.PI / 180.0;

}

/*

* 将压缩后的位置点信息写入到文件中

* */

public static void writeTestPointToFile(File outGPSFile,ArrayList pGPSPointFilter)throws Exception{

Iterator iFilter = pGPSPointFilter.iterator();

RandomAccessFile rFilter = new RandomAccessFile(outGPSFile,"rw");

while(iFilter.hasNext()){

ENPoint p = iFilter.next();

String sFilter = p.getResultString();

byte[] bFilter = sFilter.getBytes();

rFilter.write(bFilter);

}

rFilter.close();

}

/**

* 函数功能:求平均距离误差

* 返回平均距离

*/

public static double getMeanDistError(ArrayList pGPSArray,ArrayList pGPSArrayRe){

double sumDist = 0.0;

for (int i=1;i

double="" end="pGPSArrayRe.get(i).id;" int="" j="start+1;j

import java.text.DecimalFormat;

public class ENPoint implements Comparable{

public int id;

//点ID

public double pe;

//经度

public double pn;

//维度

public ENPoint(){

}

//空构造函数

public String toString(){

return this.id+"#"+this.pn+","+this.pe;

}

public String getResultString(){

DecimalFormat df = new DecimalFormat("0.000000");

return this.id+"#"+df.format(this.pe)+","+df.format(this.pn)+" \n";

}

@Override

public int compareTo(ENPoint other) {

if(this.idother.id) return 1; else

return 0;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。