package osm.jp.coverage.busstop;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import jp.co.areaweb.tools.database.*;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DbBusstop {
public static final String TABLE_NAME = "bus_stop";
public static boolean DROP = false;
File inputFile;
String filter = "";
int iCounter = 0;
String urlStr = "";
Connection con;
String timeStampStr = null;
File dir = null;
/** メイン
* 動作条件; HSQLDBのフォルダを削除した状態で実行すること。
* フォルダを削除しないで実行する場合は「-DROP」オプションを使うこと
* @param args
* @throws IOException
* @throws SQLException
* @throws ClassNotFoundException
* @throws FileNotFoundException
* @throws javax.xml.parsers.ParserConfigurationException
* @throws org.xml.sax.SAXException */
public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, IOException, SQLException, ParserConfigurationException, SAXException
{
for (String arg : args) {
if (arg.toUpperCase().equals("-DROP")) {
DROP = true;
}
}
// HSQLディレクトリがなければエラー
File dbdir = new File("database");
if (!dbdir.isDirectory()) {
throw new FileNotFoundException("Directory 'database' is not found.");
}
Connection conHsql = null;
try {
conHsql = DatabaseTool.openDb("database");
if (DROP) {
dropTable(conHsql);
}
create(conHsql);
try (PreparedStatement ps = conHsql.prepareStatement("DELETE FROM "+ TABLE_NAME)) {
ps.executeUpdate();
}
/**
* 都道府県ごとのGMLディレクトリの処理
*/
int fcounter = 0;
File dir = new File("GML_BUSSTOP");
for (File gmldir : dir.listFiles()) {
if (checkGMLdir(gmldir)) {
// GMLディレクトリを処理する
int areacode = Integer.parseInt(gmldir.getName().substring(GML_DIR_PREFIX.length(), GML_DIR_PREFIX.length()+2));
File[] files = gmldir.listFiles();
for (File iFile : files) {
// 対象のファイルが「数値地図情報のGMLデータファイル」の時のみ処理を行う。
if (checkFile(iFile, areacode)) {
importBusstop(conHsql, iFile, areacode);
fcounter++;
}
}
}
}
System.out.println("["+ fcounter +"]つのGMLファイルをインポートしました。");
DbBusstop.export(conHsql);
}
finally {
if (conHsql != null) {
DatabaseTool.closeDb(conHsql);
}
}
}
/**
* 数値地図情報のGMLデータファイルを読み取ってローカルベータベースへ記録する
* @param conHsql
* @param iFile
* @param areacode
* @throws FileNotFoundException
* @throws ClassNotFoundException
* @throws SQLException
* @throws IOException
* @throws ParserConfigurationException
* @throws SAXException
*/
public static void importBusstop (Connection conHsql, File iFile, int areacode) throws FileNotFoundException, ClassNotFoundException, SQLException, IOException, ParserConfigurationException, SAXException {
int iCounter = 0;
String timeStampStr = null;
String iStr = iFile.getName();
DocumentBuilderFactory factory;
DocumentBuilder builder;
Node root;
factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
factory.setIgnoringElementContentWhitespace(true);
factory.setIgnoringComments(true);
factory.setValidating(true);
root = builder.parse(iFile);
iCounter += showNodes(conHsql, root, iStr.substring(0, iStr.length() - 4), areacode);
System.out.println("("+ areacode +") バス停数["+ iCounter +"]");
}
/**
*
* @param con
* @param node
* @param iFileName // ソースファイル名(拡張子を含まない)
* @param areacode
* @return
* @throws IOException
* @throws SQLException
*/
public static int showNodes(Connection con, Node node, String iFileName, int areacode) throws IOException, SQLException {
int iCounter = 0;
NodeList nodes = node.getChildNodes();
for (int i=0; i<nodes.getLength(); i++) {
Node node2 = nodes.item(i);
switch (node2.getNodeName()) {
case "gml:Point":
showGmlPoint(con, node2, areacode);
break;
case "ksj:BusStop":
iCounter++;
showBusStop(con, node2, iFileName);
break;
default:
iCounter += showNodes(con, node2, iFileName, areacode);
break;
}
}
return iCounter;
}
/*
public static void showGmPoint(Connection con, Node node) throws IOException, SQLException {
String positionStr = "";
String latStr = "";
String lonStr = "";
String idStr = "";
NamedNodeMap nodeMap = node.getAttributes();
if ( null != nodeMap ) {
for ( int j=0; j<nodeMap.getLength(); j++ ) {
if (nodeMap.item(j).getNodeName().equals("id")) {
idStr = nodeMap.item(j).getNodeValue();
}
}
}
NodeList nodes = node.getChildNodes();
for (int i=0; i < nodes.getLength(); i++) {
Node node2 = nodes.item(i);
if (node2.getNodeName().equals("jps:GM_Point.position")) {
NodeList nodes3 = node2.getChildNodes();
for (int j=0; j < nodes3.getLength(); j++) {
Node node3 = nodes3.item(j);
if (node3.getNodeName().equals("jps:DirectPosition")) {
NodeList nodes4 = node3.getChildNodes();
for (int k=0; k < nodes4.getLength(); k++) {
Node node4 = nodes4.item(k);
if (node4.getNodeName().equals("DirectPosition.coordinate")) {
positionStr = node4.getTextContent();
String[] str4Ary = positionStr.split(" ");
latStr = str4Ary[0];
lonStr = str4Ary[1];
break;
}
}
break;
}
}
try (PreparedStatement ps6 = con.prepareStatement("UPDATE bus_stop SET lat=?,lon=?,fixed=? WHERE gmlid=?")) {
double lat = Double.parseDouble(latStr);
double lon = Double.parseDouble(lonStr);
ps6.setDouble(1, lat);
ps6.setDouble(2, lon);
// ps6.setInt(3, (ConvBusstop.nocheck ? 0 : HttpGET.getMap(lat, lon, NEER)));
ps6.setInt(3, 0);
ps6.setString(4, idStr);
System.out.println("UPDATE bus_stop("+ idStr +") lat="+ lat +", lon="+ lon +", fixed=0");
ps6.executeUpdate();
}
}
}
}
*/
/**
* <gml:Point gml:id="n1">
* <gml:pos>35.14591397 139.10569573</gml:pos>
* </gml:Point>
*
* @param con
* @param node
* @param areacode
* @throws IOException
* @throws SQLException
*/
public static void showGmlPoint(Connection con, Node node, int areacode) throws IOException, SQLException {
String positionStr = "";
String latStr = "";
String lonStr = "";
String idStr = "";
NamedNodeMap nodeMap = node.getAttributes();
if ( null != nodeMap ) {
for ( int j=0; j<nodeMap.getLength(); j++ ) {
if (nodeMap.item(j).getNodeName().equals("gml:id")) {
idStr = nodeMap.item(j).getNodeValue();
}
}
}
NodeList nodes = node.getChildNodes();
for (int i=0; i < nodes.getLength(); i++) {
Node node2 = nodes.item(i);
if (node2.getNodeName().equals("gml:pos")) {
positionStr = node2.getTextContent().trim();
String[] str4Ary = positionStr.split(" ");
latStr = str4Ary[0];
lonStr = str4Ary[1];
try (PreparedStatement ps6 = con.prepareStatement("INSERT INTO bus_stop (lat,lon,fixed,area,gmlid) VALUES (?,?,?,?,?)")) {
double lat = Double.parseDouble(latStr);
double lon = Double.parseDouble(lonStr);
System.out.println("INSERT INTO bus_stop (lat,lon,fixed,area, gmlid) VALUES ('"+ latStr +"','"+ lonStr +"','0',"+ areacode +",'"+ idStr +"')");
ps6.setDouble(1, lat);
ps6.setDouble(2, lon);
ps6.setInt(3, 0);
ps6.setInt(4, areacode);
ps6.setString(5, idStr);
ps6.executeUpdate();
}
}
}
}
/**
*
* @param con
* @param node
* @param iFileName // ソースファイル名(拡張子を含まない)
* @throws IOException
* @throws SQLException
*/
/*
public static void showED01(Connection con, Node node, String iFileName) throws IOException, SQLException {
String gmlidStr = "";
String nameStr = "";
PreparedStatement ps1 = con.prepareStatement("SELECT gmlid FROM bus_stop WHERE gmlid=?");
PreparedStatement ps2 = con.prepareStatement("INSERT INTO bus_stop (gmlid,name,ifile) VALUES (?,?,?)");
try {
ArrayList<String[]> bris = new ArrayList<>();
NodeList nodes = node.getChildNodes();
for (int i=0; i < nodes.getLength(); i++) {
Node node2 = nodes.item(i);
switch (node2.getNodeName()) {
case "ksj:POS":
NamedNodeMap nodeMap = node2.getAttributes();
if (null != nodeMap) {
for ( int j=0; j < nodeMap.getLength(); j++ ) {
if (nodeMap.item(j).getNodeName().equals("gmlid")) {
gmlidStr = nodeMap.item(j).getNodeValue();
System.out.println("found gmlid='"+ gmlidStr +"'");
break;
}
}
} break;
case "ksj:BSN":
nameStr = node2.getTextContent();
break;
case "ksj:BRI":
String[] rtn = anaComm(node2);
if (rtn != null) {
bris.add(rtn);
} break;
default:
break;
}
}
// gmlid と nameStr をデータベースに格納する
boolean insert = true;
ps1.setString(1, gmlidStr);
try (ResultSet rset = ps1.executeQuery()) {
if (rset.next()) {
insert = false;
}
}
if (insert) {
ps2.setString(1, gmlidStr);
ps2.setString(2, nameStr);
ps2.setString(3, iFileName);
System.out.println("INSERT INTO bus_stop (gmlid,name,ifile) VALUES ('"+ gmlidStr +"','"+ nameStr +"','"+ iFileName +"')");
ps2.executeUpdate();
}
}
finally {
ps1.close();
ps2.close();
}
}
*/
/**
* <ksj:BusStop gml:id="ED01_1">
* <ksj:position xlink:href="#n1"/>
* <ksj:busStopName>城堀</ksj:busStopName>
* <ksj:busRouteInformation>
* <ksj:BusRouteInformation>
* <ksj:busType>1</ksj:busType>
* <ksj:busOperationCompany>箱根登山バス</ksj:busOperationCompany>
* <ksj:busLineName>小01</ksj:busLineName>
* </ksj:BusRouteInformation>
* </ksj:busRouteInformation>
* <ksj:busRouteInformation>
* <ksj:BusRouteInformation>
* <ksj:busType>1</ksj:busType>
* <ksj:busOperationCompany>箱根登山バス</ksj:busOperationCompany>
* <ksj:busLineName>湯07</ksj:busLineName>
* </ksj:BusRouteInformation>
* </ksj:busRouteInformation>
* <ksj:busRouteInformation>
* <ksj:BusRouteInformation>
* <ksj:busType>1</ksj:busType>
* <ksj:busOperationCompany>箱根登山バス</ksj:busOperationCompany>
* <ksj:busLineName>湯11</ksj:busLineName>
* </ksj:BusRouteInformation>
* </ksj:busRouteInformation>
* </ksj:BusStop>
*
* @param con
* @param node
* @param iFileName // ソースファイル名(拡張子を含まない)
* @throws IOException
* @throws SQLException
*/
public static void showBusStop(Connection con, Node node, String iFileName) throws IOException, SQLException {
String gmlidStr = "";
String nameStr = "";
try (PreparedStatement ps2 = con.prepareStatement("UPDATE bus_stop SET name=?,ifile=? WHERE gmlid=?")) {
ArrayList<String[]> bris = new ArrayList<>();
NodeList nodes = node.getChildNodes();
for (int i=0; i < nodes.getLength(); i++) {
Node node2 = nodes.item(i);
switch (node2.getNodeName()) {
case "ksj:position":
NamedNodeMap nodeMap = node2.getAttributes();
if (null != nodeMap) {
for ( int j=0; j < nodeMap.getLength(); j++ ) {
if (nodeMap.item(j).getNodeName().equals("xlink:href")) {
gmlidStr = nodeMap.item(j).getNodeValue();
gmlidStr = gmlidStr.substring(1);
System.out.println("found gmlid='"+ gmlidStr +"'");
break;
}
}
} break;
case "ksj:busStopName":
nameStr = node2.getTextContent();
break;
case "ksj:busRouteInformation":
String[] rtn = anaCommJGD(node2);
if (rtn != null) {
bris.add(rtn);
} break;
default:
break;
}
}
// gmlid と nameStr をデータベースに格納する
ps2.setString(1, nameStr);
ps2.setString(2, iFileName);
ps2.setString(3, gmlidStr);
ps2.executeUpdate();
}
}
public static String[] anaComm(Node briNode) {
String[] rtn = new String[3];
rtn[0] = ""; // corp type
rtn[1] = ""; // course name
rtn[2] = ""; // corp name
NodeList nodes = briNode.getChildNodes();
for (int i=0; i < nodes.getLength(); i++) {
Node node2 = nodes.item(i);
switch (node2.getNodeName()) {
case "ksj:BSC":
rtn[0] = node2.getTextContent();
break;
case "ksj:BLN":
rtn[1] = node2.getTextContent();
break;
case "ksj:BOC":
rtn[2] = node2.getTextContent();
break;
default:
break;
}
}
return rtn;
}
/**
*
* <ksj:busRouteInformation>
* <ksj:BusRouteInformation>
* <ksj:busType>1</ksj:busType>
* <ksj:busOperationCompany>箱根登山バス</ksj:busOperationCompany>
* <ksj:busLineName>小01</ksj:busLineName>
* </ksj:BusRouteInformation>
* </ksj:busRouteInformation>
*
* @param briNode
* @return
*/
public static String[] anaCommJGD(Node briNode) {
String[] rtn = new String[3];
int vcnt = 0;
NodeList nodes2 = briNode.getChildNodes();
for (int i=0; i < nodes2.getLength(); i++) {
Node node2 = nodes2.item(i);
if (node2.getNodeName().equals("ksj:BusRouteInformation")) {
NodeList nodes3 = node2.getChildNodes();
for (int j=0; j < nodes3.getLength(); j++) {
Node node3 = nodes3.item(j);
switch (node3.getNodeName()) {
case "ksj:busType":
rtn[0] = node3.getTextContent();
vcnt++;
break;
case "ksj:busLineName":
rtn[1] = node3.getTextContent();
vcnt++;
break;
case "ksj:busOperationCompany":
rtn[2] = node3.getTextContent();
vcnt++;
break;
default:
break;
}
}
}
}
if (vcnt > 0) {
return rtn;
}
return null;
}
/**
* 'table.BUS_STOP'を新規に作る
* 既にテーブルが存在する時には何もしない
* @param conHsql
* @throws SQLException
*/
public static void create(Connection conHsql) throws SQLException {
String createSt;
// 'table.BUS_STOP'を新規に作る
createSt = "CREATE TABLE bus_stop (gmlid VARCHAR(12) NOT NULL, gid LONG, name VARCHAR(128), kana VARCHAR(128), lat DOUBLE, lon DOUBLE, fixed INT, area INT, ifile VARCHAR(128), up INT, CONSTRAINT bus_stop_pk PRIMARY KEY(gmlid));";
create(conHsql, createSt);
//createSt = "CREATE TABLE existing_data (gmlid VARCHAR(12) NOT NULL, name VARCHAR(128), lat DOUBLE, lon DOUBLE, score INT, CONSTRAINT existing_pk PRIMARY KEY(gmlid, lat, lon));";
//create(conHsql, createSt);
//createSt = "CREATE TABLE coverage (area INT, name VARCHAR(128), denominator BIGINT, lv1 BIGINT, lv2 BIGINT, lv3 BIGINT);";
//create(conHsql, createSt);
}
static void create(Connection con, String createsql) throws SQLException {
System.out.println(createsql);
try (PreparedStatement ps = con.prepareStatement(createsql)) {
ps.executeUpdate();
}
catch (SQLSyntaxErrorException e) {
System.out.println("83:"+ e.toString());
if (!(e.toString().startsWith("java.sql.SQLSyntaxErrorException: object name already exists:"))) {
throw e;
}
}
}
/**
* 'table.BUS_STOP'を削除する
* @param conHsql
* @throws java.io.FileNotFoundException
* @throws java.lang.ClassNotFoundException
* @throws SQLException
* @throws javax.xml.parsers.ParserConfigurationException
* @throws org.xml.sax.SAXException
*/
public static void dropTable (Connection conHsql) throws FileNotFoundException, ClassNotFoundException, SQLException, IOException, ParserConfigurationException, SAXException {
drop(conHsql, "bus_stop");
//drop(conHsql, "existing_data");
//drop(conHsql, "coverage");
}
public static void drop(Connection con, String tableName) throws SQLException {
String createSt = "DROP TABLE "+ tableName +";";
System.out.println(createSt);
try (PreparedStatement ps = con.prepareStatement(createSt)) {
ps.executeUpdate();
}
catch (SQLSyntaxErrorException e) {
System.out.println("107:"+ e.toString());
if (!(e.toString().startsWith("java.sql.SQLSyntaxErrorException: user lacks privilege or object not found:"))) {
throw e;
}
}
}
/**
* 'table.BUS_STOP'の内容をCSV形式にして標準出力に出力する
* @param con
*/
public static void export(Connection con) {
try {
System.out.println("TABLE: BUS_STOP");
System.out.println("\"name\",\"lat\",\"lon\",\"fixed\",\"ifile\"");
PreparedStatement ps8 = con.prepareStatement("SELECT name,lat,lon,fixed,ifile FROM bus_stop");
try (ResultSet rset8 = ps8.executeQuery()) {
while (rset8.next()) {
String name = rset8.getString(1);
Double lat = rset8.getDouble(2);
Double lon = rset8.getDouble(3);
int fixed = rset8.getInt(4);
String ifile = rset8.getString(5);
System.out.println("\""+ name +"\","+ lat +","+ lon +","+ fixed +",\""+ ifile +"\"");
}
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 数値地図情報のGMLデータファイルかどうかを見極める
* @param f
* @return
*/
static boolean checkFile(File f, int areacode) {
String name = f.getName();
if (!name.startsWith(GML_DIR_PREFIX)) {
return false;
}
if (!name.toUpperCase().endsWith(".XML")) {
return false;
}
return Integer.parseInt(name.substring(GML_DIR_PREFIX.length(), GML_DIR_PREFIX.length()+2)) == areacode;
}
/**
* 数値地図情報のデータディレクトリかどうかを見極める
* @param f
* @return
*/
public static boolean checkGMLdir(File f) {
if (!f.isDirectory()) {
return false;
}
String name = f.getName();
if (!name.startsWith(GML_DIR_PREFIX)) {
return false;
}
return name.toUpperCase().endsWith(GML_DIR_PRIFIX);
}
public static final String GML_DIR_PREFIX = "P11-10_";
public static final String GML_DIR_PRIFIX = "_GML";
}