背景
在船舶业务中,航线是重要的要素。传统的航线是在纸质上标识,目前需要将纸质的电子化,即绘制成航线地图。航线数据在原有系统中,是以二维表的方式存储,格式为,例子:
釜山/青岛/上海/宁波/香港(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];