本人在做矿山定位系统,原本的构思是:
只有基站不坏,数据库存储(来自工人佩戴在手上的手环信息)完好,我绘制了相邻基站之间所有的可能的路线,也自己模拟测试了可以运动;
但是现实情况是:
一:手环在剧烈运动下信号不稳,数据就不会通过基站发送过来,
二:几百个人同时下井的话,多线程浪费时间;接受数据太快以至于存储到数据库里存在空白或者少量的数据丢失;
这些都涉及更稳定的线程池和栈队列这些,时间太紧,只能在绘制轨迹上下功夫
三:
如果存在遗漏信息的话,基站之间的路线就不完整,需要人为的去识别,总共30多个基站,有可能数据库收到的基站第一个和第二个之间在实际的图纸上面相隔了1-n个基站,基站之间的组合有数千数万种,即使有时间去做,也不方便后期的基站添加和维护;
故:
需要一个算法来解决判断是隔了一个还是隔几个基站还是相邻的情况;
以下代码是我测试成功的代码:
适用于:
相邻或间隔一个基站之间的轨迹
package cn.com.gj;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class WW {
public static List<Route> lr=null;//寻找中介时的集合
public static List<Route> lh=null;
public static List<Route> ll=null;//最终的路线轨迹
public static void main(String[] args) {
//1.模拟一个数据库,目的是不用老是重启tomcat,假设数据库里存储了30,20号基站,不相邻的
List<String> list=new ArrayList<String>();
list.add("022");
list.add("030");
//2.筛选出运动轨迹出来
BufferedImage bi=new BufferedImage(500, 500, BufferedImage.TYPE_INT_BGR);
Graphics2D gh = bi.createGraphics();
//2.1集合里如果只有一个数的话
//2.2取集合里面的第一第二个数
int sa=0;
int sb=0;
int ea=0;
int eb=0;
List<Route> l2=null;
for (int i = 0; i < list.size()-1; i++) {
int sz[]= case1(list.get(i),sa,sb);//#30的x y左边
int zz[]=case1(list.get(i+1), ea, eb);//#20的x y左边
//2.3开始寻找合适的路线
l2=drawline(gh, sz[0], sz[1], zz[0], zz[1]);
//ll是空的,但是由于集合第一个是arraylist数组,虽然数组是空的,但是有大小所以为1
if(l2.get(0)!=null){
//2.3.1属于邻居关系、可以直达的路线
ll=new ArrayList<Route>();
Route re=new Route(sz[0], sz[1], zz[0], zz[1]);
ll.add(re);
System.out.println("直接关系:");
}else{
//2.3.2属于隔了一个的关系,需要有一个中介才可以直达
//2.3.2.1 如果不是直接关系,先把所有开始位置坐标的线段找出来,然后把每个线段的末尾坐标作为开始坐标,集合里面末尾坐标还是末尾坐标,如果存在就是这个中间线段
drawline(gh, sz[0], sz[1], zz[0], zz[1]);
for (Route rr : lr) {
l2=null;
l2=drawline(gh,rr.getStartb(), rr.getEndb(),zz[0], zz[1] );
if(l2.get(0)!=null){
System.out.println("邻居关系");
//1.由于集合无论是否添加一个数组,大小都是1,所以需要判断第一个是不是空的就可以了
ll=new ArrayList<Route>();
Route re=new Route(sz[0], sz[1], rr.getStartb(), rr.getEndb());
ll.add(re);
Route re1=new Route (rr.getStartb(), rr.getEndb(),zz[0],zz[1]);
ll.add(re1);
}
//System.out.println(rr.getStartb()+"==="+rr.getEndb());
}
}//for结束
for (Route rr2 : ll) {
System.out.println(rr2.getStarta()+":"+rr2.getEnda()+":"+rr2.getStartb()+":"+rr2.getEndb());
}
}
}
//递归函数
public static List<Route> drawline(Graphics gh,int sa,int sb,int ea,int eb) {
List<Route> list=new ArrayList<Route>();
// 1.1#30
Route rr =null;
if( sa== 71 && sb == 96 ){
lr=new ArrayList<Route>();
Route r = null;
//@22
if(ea == 72 && eb== 281){
gh.drawLine(71,96,72,281);
rr = new Route(sa, sb, ea, eb);
}
//lr是所有的以71,96为开始的线段的集合
r=new Route(71,96,72,281);
lr.add(r);
}
//#22
if( sa== 72 && sb == 281){
//@30
lr=new ArrayList<Route>();
Route r = null;
if(ea== 71 && eb == 96){
gh.drawLine(72,281,71,96);
rr = new Route(sa, sb, ea, eb);
}
//@22
else if(ea == 337 && eb == 281){
gh.drawLine(72,281,337,281);
rr = new Route(sa, sb, ea, eb);
System.out.println("添加了我!");
}
r=new Route(72,281,337,281);
lr.add(r);
r=new Route(72,281,71,96);
lr.add(r);
}
//#20
if(sa== 337 && sb == 281){
//22==20
lr=new ArrayList<Route>();
Route r = null;
if(ea == 72 && eb == 281){
gh.drawLine(337,281,72,281);
rr = new Route(sa, sb, ea, eb);
}
else if(ea == 396 && eb == 282) {
gh.drawLine(337, 281, 396, 282);// 20#--12#(1)
rr = new Route(sa, sb, ea, eb);
}
r=new Route(337,281,72,281);
lr.add(r);
r=new Route(337, 281, 396, 282);
lr.add(r);
}
//#12
if( sa == 396 && sb == 282){
//20==12
lr=new ArrayList<Route>();
Route r = null;
if(ea == 337 && eb == 281) {
gh.drawLine(396, 282,337, 281);// 20#--12#(1)
rr= new Route(sa, sb, ea, eb);
}
r=new Route(396, 282,337, 281);
lr.add(r);
}
//#21
if( sa == 507 && sb == 286){
//15
lr=new ArrayList<Route>();
Route r = null;
if(ea == 580 && eb == 286) {
gh.drawLine(507, 286,580, 286);// 21--15
rr= new Route(sa, sb, ea, eb);
}
//#20
if(ea == 337 && eb == 281) {
gh.drawLine(507, 286,337, 281);// 21--15
rr= new Route(sa, sb, ea, eb);
}
r=new Route(507, 286,580, 286);
lr.add(r);
r=new Route(507, 286,337, 281);
lr.add(r);
}
//端点15
if( sa == 580 && sb == 286){
//15-21
lr=new ArrayList<Route>();
Route r = null;
if(ea == 507 && eb == 286) {
gh.drawLine(580, 286,507, 286);
rr= new Route(sa, sb, ea, eb);
}
r=new Route(580, 286,507, 286);
lr.add(r);
}
list.add(rr);
return list;
}
//知道#30 #20基站的坐标
private static int[] case1(String a, int x, int y) {
switch (a) {
case "030":
x = 71;
y = 96;
break;
case "017":
x = 145;
y = 86;
break;
case "022":
x = 72;
y = 281;
break;
case "020":
x = 337;
y = 281;
break;
case "028":
x = 352;
y = 80;
break;
case "012":
x = 396;
y = 282;
break;
case "014":
x = 420;
y = 71;
break;
case "023":
x = 441;
y = 70;
break;
case "029":
x = 509;
y = 58;
break;
case "013":
x = 441;
y = 326;
break;
case "019":
x = 503;
y = 378;
break;
case "027":
x = 600;
y = 463;
break;
case "024":
x = 149;
y = 462;
break;
case "040":
x = 149;
y = 560;
break;
case "038":
x = 736;
y = 561;
break;
case "033":
x = 690;
y = 575;
break;
case "015":
x = 580;
y = 286;
break;
case "039":
x = 446;
y = 547;
break;
case "037":
x = 446;
y = 596;
break;
case "031":
x = 656;
y = 564;
break;
case "034":
x = 656;
y = 564;
break;
case "036":
x = 549;
y = 642;
break;
case "026":
x = 549;
y = 642;
break;
case "011":
x = 694;
y = 678;
break;
case "016":
x = 444;
y = 649;
break;
case "032":
x = 690;
y = 626;
break;
case "021":
x = 507;
y = 286;
break;
case "035":
x = 650;
y = 657;
break;
case "025":
x = 650;
y = 601;
break;
}
int[] sz = { x, y };
return sz;
}
}
模拟数据库只有22和12号基站的话;中间20号基站没有收到;
我们一般绘制运动轨迹只能是相邻基站之间的轨迹,如果面面俱到,工程量大,不易修改!
所以需要用到算法和递归;