自动生成航线的思路和核心代码
来源:互联网 发布:qq群一键群发软件 编辑:程序博客网 时间:2024/06/06 01:21
背景
在船舶业务中,航线是重要的要素。传统的航线是在纸质上标识,目前需要将纸质的电子化,即绘制成航线地图。航线数据在原有系统中,是以二维表的方式存储,格式为,例子:
釜山/青岛/上海/宁波/香港(CHT/HIT)/盐田/南沙/新加坡/苏伊士运河/比雷埃夫斯(希腊)/拉斯佩齐亚(意大利)/热那亚(意大利)/巴塞罗那(西班牙)/巴伦西亚(西班牙)/比雷埃夫斯(希腊)/苏伊士运河/新加坡/头顿(越南)/香港(CHT/HIT)
除了航线数据,同时还提供了每个港口的坐标信息。
思路
由于航线比较多,而且以后还会开发新的航线,如果直接采用人工的方式,效率会比较低。所以想用程序的方式实现,具体思路如下:
- 分解航线成航段(删除重复的航段),每条航段格式:开始港口-结束港口;
- 利用ST_Geometry函数构建航段,即线要素;
- 对航段进行人工手动处理。由于构建的航段为直线,直接横跨大陆,而船舶是在海上行驶,并不符合要求,所以需要对部分横跨大陆的航段进行人工处理;
- 将航段组合成航线,也是利用到了ST_Geometry函数。
数据结构
港口表:
原始航线表:
航段表:
航段-航线关系表:
航线表:
核心代码
/**
* @Title: createRouteSegment
* @Description: 根据航线表创建航段要素(航段为直线)
* @param@param ports
* @return void
* @throws
*/
publicvoid createRouteSegment() {
try {
Connection conn = Conn.getConnection();
Statement stmt = conn
.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// 查询航线表,并过滤不必要的港口名称,并分拆成航段
List<Segment> segments = new ArrayList<Segment>(); // 航段表
String sqlByTRoute = "select routeid,waytoports from t_route";
ResultSet rs = stmt.executeQuery(sqlByTRoute);
while (rs.next()) {
String routeID = rs.getString("routeid");
String waytoports = rs.getString("waytoports");
waytoports = waytoports.replace("(CHT/HIT)", "");
waytoports = waytoports.replace("(Document only)", "");
waytoports = waytoports.replace("(MTL)", "");
waytoports = waytoports.replace("(HIT)", "");
waytoports = waytoports.replace("(CMCS)", "");
waytoports = waytoports.replace("(HIT/CHT)", "");
waytoports = waytoports.replace("(HIT/MTL)", "");
waytoports = waytoports.replace("(ACT)", "");
waytoports = waytoports.replace("(MTL/HIT)", "");
waytoports = waytoports.replace("(CHI/HIT)", "");
waytoports = waytoports.replace("(HIT/DP world)", "");
String[] portArray = waytoports.split("/"); // 分拆成港口数组
String startPort; // 起点港口
String endPort; // 终点港口
for (inti = 0; i < portArray.length - 1; i++) {
startPort = portArray[i];
endPort = portArray[i + 1];
if (startPort.contains("(")) {
startPort = startPort.substring(0,
startPort.indexOf("("));
}
if (startPort.contains("(")) {
startPort = startPort.substring(0,
startPort.indexOf("("));
}
if (endPort.contains("(")) {
endPort = endPort.substring(0, endPort.indexOf("("));
}
if (endPort.contains("(")) {
endPort = endPort.substring(0, endPort.indexOf("("));
}
Segment vo = new Segment();
vo.setRouteID(routeID); // 航线编码
vo.setOrderID(i + 1); // 航段序号
vo.setStartPort(startPort); // 航段开始港口
vo.setEndPort(endPort);// 航段结束港口
segments.add(vo);
}
}
System.out.println("分拆航线后,总的航段数:" + segments.size());
// 删除重复的航段,并给航段编码,以及配置坐标
List<Segment> delRepSegments = new ArrayList<Segment>(); // 已删除过重复的航段集合
List<Segment> copyRepeatSegments = new ArrayList<Segment>(); // 重新构建一个新区域存储航段数据,避免和原有的航段数据重合
copyRepeatSegments.addAll(segments); // 复制一份,避免修改原有的航段数据
Iterator<Segment> it = copyRepeatSegments.iterator();
intstartSegmentIDNumber = 1;
while (it.hasNext()) {
Segment a = it.next();
booleanflag = true;
for (inti = 0; i < delRepSegments.size(); i++) {
if (delRepSegments.get(i).getStartPort()
.equals(a.getStartPort())
&& delRepSegments.get(i).getEndPort()
.equals(a.getEndPort())) {
it.remove();
flag = false;
break;
}
}
if (flag) {
a.setSegmentID("S00" + startSegmentIDNumber); // 航段编码
startSegmentIDNumber++;
delRepSegments.add(a);
}
}
System.out.println("删除重复的航段后,剩余航段数:" + delRepSegments.size());
// 循环构建每段航段的所属航线编码、对应航段的序号
for (inti = 0; i < segments.size(); i++) {
for (intj = 0; j < delRepSegments.size(); j++) {
if (segments.get(i).getStartPort()
.equals(delRepSegments.get(j).getStartPort())
&& segments.get(i).getEndPort()
.equals(delRepSegments.get(j).getEndPort())) {
segments.get(i).setSegmentID(
delRepSegments.get(j).getSegmentID()); // 配置关系表中的航段编码
break;
}
}
}
PreparedStatement pstmt = null;
for (inti = 0; i < segments.size(); i++) {
String segmentSQL = "INSERT INTO r_routetosegment(objectid,routeid,segmentid,orderid) VALUES(?, ?, ?, ?)";
pstmt = conn.prepareStatement(segmentSQL);
pstmt.setInt(1, (i + 1));
pstmt.setString(2, segments.get(i).getRouteID());
pstmt.setString(3, segments.get(i).getSegmentID());
pstmt.setInt(4, segments.get(i).getOrderID());
pstmt.execute();
}
System.out.println("关系表ID入库成功!");
// 给航段上的港口配置坐标,循环查询所有的航段起止港口坐标
for (Segment vo : delRepSegments) {
// 查询航段的开始港口坐标
String startPortSQL = "select x,y from port where portname='"
+ vo.getStartPort() + "'";
rs = stmt.executeQuery(startPortSQL);
while (rs.next()) {
vo.setStartX(rs.getString("x"));
vo.setStartY(rs.getString("y"));
}
// 查询航段的截止港口坐标
String endPortSQL = "select x,y from port where portname='"
+ vo.getEndPort() + "'";
rs = stmt.executeQuery(endPortSQL);
while (rs.next()) {
vo.setEndX(rs.getString("x"));
vo.setEndY(rs.getString("y"));
}
}
// 生成航段
for (intj = 0; j < delRepSegments.size(); j++) {
Segment segment = delRepSegments.get(j); // 一段航段
String segmentLineSQL = "INSERT INTO segment(objectid, segmentid, startport, endport, shape) VALUES ("
+ (j + 1)
+ ",'"
+ segment.getSegmentID()
+ "','"
+ segment.getStartPort()
+ "','"
+ segment.getEndPort()
+ "',sde.st_geometry ('linestring("
+ segment.getStartX()
+ " "
+ segment.getStartY()
+ ","
+ segment.getEndX()
+ " "
+ segment.getEndY()
+ ")', 3857));";
System.out.println(segmentLineSQL);
stmt.executeUpdate(segmentLineSQL);
}
System.out.println("生成新航段成功!");
rs.close();
pstmt.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Title: createRouteBySegment
* @Description: 根据已有的航段创建航线(航段已经经过人工调整,避开了大陆部分)
* @param
* @return void
* @throws
*/
publicvoid createRouteBySegment() {
List<Route> routeList = new ArrayList<Route>(); // 航线集合
String sql = "select routeid, direction, company, agent, waytoports from t_route order by objectid";
try {
Connection conn = Conn.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
Route route = new Route();
route.setRouteID(rs.getString("routeid"));
route.setDirection(rs.getString("direction"));
route.setCompany(rs.getString("company"));
route.setAgent(rs.getString("agent"));
route.setWaytoports(rs.getString("waytoports"));
routeList.add(route);
}
// 查询每条航线上的所有航段编码
for (inti = 0; i < routeList.size(); i++) {
Route route = routeList.get(i); // 一条航线
String sqlSegment = "SELECT segmentid FROM r_routetosegment WHERE routeid='"
+ route.getRouteID() + "';";
rs = stmt.executeQuery(sqlSegment);
List<String> segmentids = new ArrayList<String>(); // 航线上的所有航段编码
while (rs.next()) {
segmentids.add(rs.getString("segmentid"));
}
route.setSegmentids(segmentids); // 航线上的所有航段编码
}
// 根据已生成的航段,构建航线并入库
for (inti = 0; i < routeList.size(); i++) {
Route route = routeList.get(i); // 一条航线
String sqlRoute = "INSERT INTO szroute(objectid, routeid, direction, company, agent, waytoports, shape) VALUES("
+ (i + 1)
+ ",'"
+ route.getRouteID()
+ "','"
+ route.getDirection()
+ "','"
+ route.getCompany()
+ "','"
+ route.getAgent()
+ "','"
+ route.getWaytoports() + "',";
String secondeValue = "";
for (intj = 0; j < route.getSegmentids().size(); j++) {
if (j == 0) {
secondeValue = secondeValue
+ "(SELECT shape FROM segment WHERE segmentid='"
+ route.getSegmentids().get(j) + "')";
} elseif (j == (route.getSegmentids().size() - 1)) {
secondeValue = "st_union("
+ secondeValue
+ ",(SELECT shape FROM segment WHERE segmentid='"
+ route.getSegmentids().get(j) + "'))";
} else {
secondeValue = "(SELECT * FROM st_union("
+ secondeValue
+ ",(SELECT shape FROM segment WHERE segmentid='"
+ route.getSegmentids().get(j) + "')))";
}
}
sqlRoute = sqlRoute + secondeValue + ");";
stmt.executeUpdate(sqlRoute);
}
System.out.println("航线入库成功!");
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
- 自动生成航线的思路和核心代码
- C#自动数据库代码生成的思路
- 自动生成MVC中的model实体类的核心代码
- 代码自动生成和抽象
- 代码自动生成和抽象
- 代码自动生成和抽象
- 代码自动生成和抽象
- 代码生成工具的实现思路
- 分享一份自己写的关于ssh框架自动生成Bean的源代码和思路
- 产品和产品规格(产品变量)自动生成SKU的需求解决思路
- java 核心代码加密思路
- 生成验证图片的核心代码!!
- 分页的核心思路
- mybatis-generator自动生成java代码和配置文件的注意事项
- Mybatis Generator 自动生成代码和常见的问题
- C++构造函数和编译器自动生成代码的陷阱
- 游戏中自动攻击最近目标、二次连击和群体攻击的大体代码思路
- 使用Encoder-Decoder模型自动生成对联的思路
- 利用Javascript脚本捕获键盘事件
- C# 单例模式整理
- jQuery的局部刷新——get、post和ajax方法写法小结
- JPEG vs PNG vs GIF
- 利用Java 第三方控件 jxl对M$ Excel 进行全操作
- 自动生成航线的思路和核心代码
- C# 字符 vs 文本元素
- 所选下拉框的name值以及多选框选中值的提交
- 在自己的主机上配置域名
- Robot Framework 中的“坑”
- ibatis的queryForMap方法研究
- POI创建table
- 从 Oracle 大字段(blob,clob)的读、写认识 Java JDBC操作全攻略
- 进制转换