Newer
Older
osmCoverage / src / osm / jp / api / Osmdb.java
@hayashi hayashi on 11 Dec 2017 14 KB [disused:amenity=fuel]
  1. package osm.jp.api;
  2.  
  3. import java.io.*;
  4. import java.sql.Connection;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.sql.SQLIntegrityConstraintViolationException;
  9. import java.sql.SQLSyntaxErrorException;
  10. import jp.co.areaweb.tools.csv.CsvRecord;
  11. import org.hsqldb.HsqlException;
  12. import org.w3c.dom.NamedNodeMap;
  13. import org.w3c.dom.Node;
  14. import org.w3c.dom.NodeList;
  15.  
  16. public abstract class Osmdb {
  17. public static final String TABLE_NAME = "OSM_EXIST";
  18.  
  19. /*
  20. public static void main(String[] args) throws MalformedURLException, ProtocolException, IOException {
  21. double minlat = 35.13d;
  22. double maxlat = 35.66d;
  23. double minlon = 138.99d;
  24. double maxlon = 139.79d;
  25. //getCapabilities(new File("output.xml"), "highway", "bus_stop", minlat, maxlat, minlon, maxlon);
  26. //getCapabilities(new File("output.xml"), "highway", "disused:bus_stop", minlat, maxlat, minlon, maxlon);
  27. //getCapabilities(new File("output.xml"), "amenity", "bus_station", minlat, maxlat, minlon, maxlon);
  28. //getCapabilities(new File("output.xml"), "public_transport", "platform", minlat, maxlat, minlon, maxlon);
  29. getCapabilities("public_transport", "stop_position", minlat, maxlat, minlon, maxlon, "node");
  30. getCapabilities("amenity", "fuel", minlat, maxlat, minlon, maxlon, "way");
  31. }
  32. */
  33. /**
  34. * 'HSQLDB.table.OSM_EXIST'を新規に作る
  35. * 'HSQLDB.table.AREA_NODE'を新規に作る
  36. * 既にテーブルが存在する時にはERROR
  37. * @param con
  38. * @throws SQLException
  39. */
  40. public static void create(Connection con) throws SQLException {
  41. String createSt;
  42. sql(con, "DROP TABLE IF EXISTS "+ Osmdb.TABLE_NAME +" CASCADE");
  43. //sql(con, "DROP INDEX "+ HttpPOST.TABLE_NAME +"_index;");
  44. sql(con, "DROP TABLE IF EXISTS AREA_NODE CASCADE");
  45.  
  46. // 'table.FUEL_EXIST'を新規に作る
  47. createSt = "CREATE TABLE "+ Osmdb.TABLE_NAME +" (idref VARCHAR(12) NOT NULL, name VARCHAR(128), lat DOUBLE, lon DOUBLE, score INT, PRIMARY KEY(idref));";
  48. Db.updateSQL(con, createSt);
  49. createSt = "CREATE INDEX "+ Osmdb.TABLE_NAME +"_index ON "+ Osmdb.TABLE_NAME +" (lat, lon);";
  50. Db.updateSQL(con, createSt);
  51.  
  52. // 'table.AREA_NODE'を新規に作る
  53. createSt = "CREATE TABLE AREA_NODE (idref VARCHAR(12) NOT NULL, pid VARCHAR(12), lat DOUBLE, lon DOUBLE);";
  54. Db.updateSQL(con, createSt);
  55. }
  56. static void sql(Connection con, String sql) throws SQLException {
  57. System.out.println(sql);
  58. try (PreparedStatement ps = con.prepareStatement(sql)) {
  59. ps.executeUpdate();
  60. }
  61. catch (SQLSyntaxErrorException e) {
  62. System.out.println("107:"+ e.toString());
  63. if (!(e.toString().startsWith("java.sql.SQLSyntaxErrorException: user lacks privilege or object not found:"))) {
  64. throw e;
  65. }
  66. }
  67. }
  68.  
  69. public static void outputWriter(PrintWriter pw, String text) {
  70. System.out.println("\t" + text);
  71. pw.print(text);
  72. }
  73. public static final int POINT_NO = 0; // 評価ポイント無し→ score=50
  74. public static final int POINT_FIXME = 1; // 評価ポイント|!(fixme=null) → score=1
  75. public static final int POINT_BRAND = 2; // 評価ポイント|brand=null → score=1
  76. public static final int POINT_NAME = 4; // 評価ポイント|name=null → score=1
  77. public static final int POINT_BUS = 8; // 評価ポイント|!(bus=yes) → score=0
  78.  
  79. public int importExistingNode(Connection hsqldb, Connection osmdb, ResultSet rset, int point) throws IOException, SQLException {
  80. String osmidStr = rset.getString("osm_id");
  81. String latStr = rset.getString("lat");
  82. String lonStr = rset.getString("lon");
  83. String brandStr = rset.getString("brand");
  84. String nameStr = rset.getString("name");
  85. String fixmeStr = "";
  86.  
  87. int score = 50;
  88. if (((point & POINT_BRAND) != 0) && isNull(brandStr)) {
  89. score = 1;
  90. }
  91. if (((point & POINT_NAME) != 0) && isNull(nameStr)) {
  92. score = 1;
  93. }
  94. boolean fixme = false;
  95. boolean busYes = false;
  96. if (((point & (POINT_FIXME | POINT_BUS)) != 0)) {
  97. PreparedStatement ps8 = osmdb.prepareStatement("SELECT * FROM planet_osm_nodes where id='"+ osmidStr +"'");
  98. try (ResultSet rset8 = ps8.executeQuery()) {
  99. while (rset8.next()) {
  100. String tags = rset8.getString("tags");
  101. if (tags != null) {
  102. tags = tags.substring(1);
  103. tags = tags.substring(0, tags.length()-1);
  104. CsvRecord csv = new CsvRecord();
  105. csv.analizeRecord(tags);
  106. boolean key = true;
  107. boolean bus = false;
  108. for (String str : csv) {
  109. if (key) {
  110. if (str.startsWith("fixme")) {
  111. fixme = true;
  112. }
  113. if (str.equals("bus")) {
  114. bus = true;
  115. }
  116. key = false;
  117. }
  118. else {
  119. if (bus) {
  120. if (str.equals("yes")) {
  121. busYes = true;
  122. }
  123. bus = false;
  124. }
  125. key = true;
  126. }
  127. }
  128. System.out.println(tags);
  129. }
  130. }
  131. }
  132. if (((point & POINT_FIXME) != 0) && fixme) {
  133. score = 1;
  134. }
  135. if (((point & POINT_BUS) != 0) && !busYes) {
  136. score = 0;
  137. }
  138. }
  139. if (score > 0) {
  140. // idref と brandStr をデータベースに格納する
  141. System.out.println("INSERT INTO "+ TABLE_NAME +" (idref,lat,lon,score,name) VALUES ("+ osmidStr +","+ latStr +","+ lonStr+","+ Integer.toString(score) +",'"+ nameStr +"')N");
  142. try (PreparedStatement ps5 = hsqldb.prepareStatement("INSERT INTO "+ TABLE_NAME +" (idref,lat,lon,score,name) VALUES (?,?,?,?,?)")) {
  143. ps5.setString(1, osmidStr);
  144. ps5.setDouble(2, Double.parseDouble(latStr));
  145. ps5.setDouble(3, Double.parseDouble(lonStr));
  146. ps5.setInt(4, score);
  147. ps5.setString(5, nameStr);
  148. ps5.executeUpdate();
  149. return 1;
  150. }
  151. catch (HsqlException | SQLIntegrityConstraintViolationException e) {
  152. // integrity constraint violation: unique constraint or index violation; SYS_PK_10069 table: FUEL_EXIST
  153. // [HsqlException]は、無視する
  154. // integrity constraint violation: unique constraint or index violation; SYS_PK_10069 table: FUEL_EXIST
  155. // [SQLIntegrityConstraintViolationException]は、無視する
  156. }
  157. }
  158.  
  159. return 0;
  160. }
  161. boolean isNull(String vstr) {
  162. if (vstr == null) {
  163. return true;
  164. }
  165. return (vstr.trim().length() < 1);
  166. }
  167. int readAreaNodes(Connection con, Node node) throws IOException, SQLException {
  168. int iCounter = 0;
  169.  
  170. NodeList nodes = node.getChildNodes();
  171. for (int i = 0; i < nodes.getLength(); i++) {
  172. Node node2 = nodes.item(i);
  173. switch (node2.getNodeName()) {
  174. case "node":
  175. iCounter++;
  176. importAreaNode(con, node2);
  177. break;
  178. default:
  179. iCounter += readAreaNodes(con, node2);
  180. break;
  181. }
  182. }
  183. return iCounter;
  184. }
  185. void importAreaNode(Connection con, Node node) throws IOException, SQLException {
  186. String idrefStr = "";
  187. String latStr = "";
  188. String lonStr = "";
  189.  
  190. NodeList nodes = node.getChildNodes();
  191. if (nodes.getLength() > 0) {
  192. return;
  193. }
  194.  
  195. NamedNodeMap nodeMap = node.getAttributes();
  196. if (nodeMap != null) {
  197. for (int j=0; j < nodeMap.getLength(); j++) {
  198. switch (nodeMap.item(j).getNodeName()) {
  199. case "id":
  200. idrefStr = nodeMap.item(j).getNodeValue();
  201. break;
  202. case "lat":
  203. latStr = nodeMap.item(j).getNodeValue();
  204. break;
  205. case "lon":
  206. lonStr = nodeMap.item(j).getNodeValue();
  207. break;
  208. default:
  209. break;
  210. }
  211. }
  212. // idref と brandStr をデータベースに格納する
  213. System.out.println("insert into AREA_NODE(idref,lat,lon) values("+ idrefStr +","+ latStr +","+ lonStr+")");
  214. try (PreparedStatement ps5 = con.prepareStatement("INSERT INTO AREA_NODE (idref,lat,lon) VALUES (?,?,?)")) {
  215. ps5.setString(1, idrefStr);
  216. ps5.setDouble(2, Double.parseDouble(latStr));
  217. ps5.setDouble(3, Double.parseDouble(lonStr));
  218. ps5.executeUpdate();
  219. }
  220. }
  221. }
  222.  
  223.  
  224.  
  225. void importExistingArea(Connection con, Node node, int point) throws IOException, SQLException {
  226. String idrefStr = "";
  227. double maxlat = -90.0D;
  228. double maxlon = -180.0D;
  229. double minlat = 90.0D;
  230. double minlon = 180.0D;
  231. String nameStr = "";
  232. String brandStr = "";
  233. String fixmeStr = "";
  234.  
  235. NamedNodeMap nodeMap = node.getAttributes();
  236. if (nodeMap != null) {
  237. for (int j=0; j < nodeMap.getLength(); j++) {
  238. switch (nodeMap.item(j).getNodeName()) {
  239. case "id":
  240. idrefStr = nodeMap.item(j).getNodeValue();
  241. break;
  242. default:
  243. break;
  244. }
  245. }
  246.  
  247. NodeList nodes = node.getChildNodes();
  248. for (int i = 0; i < nodes.getLength(); i++) {
  249. Node node2 = nodes.item(i);
  250. if (node2.getNodeName().equals("tag")) {
  251. OsmnodeTag tagnode = new OsmnodeTag(node2);
  252. String value = tagnode.getValue("brand");
  253. if (value != null) {
  254. brandStr = value;
  255. }
  256. value = tagnode.getValue("name:ja");
  257. if (value != null) {
  258. nameStr = value;
  259. }
  260. value = tagnode.getValue("name");
  261. if (value != null) {
  262. nameStr = value;
  263. }
  264. value = tagnode.getValue("fixme");
  265. if (value != null) {
  266. fixmeStr = value;
  267. }
  268. }
  269. else if (node2.getNodeName().equals("nd")) {
  270. OsmnodeNd ndnode = new OsmnodeNd(node2);
  271. String ref = ndnode.getRef();
  272. Position pos = getNdPosition(con, ref);
  273. if (pos != null) {
  274. minlat = (pos.lat < minlat ? pos.lat : minlat);
  275. minlon = (pos.lon < minlon ? pos.lon : minlon);
  276. maxlat = (pos.lat > maxlat ? pos.lat : maxlat);
  277. maxlon = (pos.lon > maxlon ? pos.lon : maxlon);
  278. }
  279. }
  280. }
  281. if ((maxlat != -90.0D) && (maxlon != -180.0D) && (minlon != 180.0D) && (minlat != 90.0D)) {
  282. double lat = (maxlat + minlat) / 2;
  283. double lon = (maxlon + minlon) / 2;
  284. int score = 50;
  285.  
  286. if (((point & POINT_BRAND) != 0) && brandStr.equals("")) {
  287. score = 1;
  288. }
  289. if (((point & POINT_NAME) != 0) && nameStr.equals("")) {
  290. score = 1;
  291. }
  292. if (((point & POINT_FIXME) != 0) && !fixmeStr.equals("")) {
  293. score = 1;
  294. }
  295.  
  296. // idref と nameStr をデータベースに格納する
  297. System.out.println("INSERT INTO "+ TABLE_NAME +" (idref,lat,lon,score,name) VALUES("+ idrefStr +","+ lat +","+ lon+","+ Integer.toString(score) +",'"+ nameStr +"');");
  298. try (PreparedStatement ps5 = con.prepareStatement("INSERT INTO "+ TABLE_NAME +" (idref,lat,lon,score,name) VALUES (?,?,?,?,?)")) {
  299. ps5.setString(1, idrefStr);
  300. ps5.setDouble(2, lat);
  301. ps5.setDouble(3, lon);
  302. ps5.setInt(4, score);
  303. ps5.setString(5, nameStr);
  304. ps5.executeUpdate();
  305. }
  306. catch (HsqlException | SQLIntegrityConstraintViolationException e) {
  307. // integrity constraint violation: unique constraint or index violation; SYS_PK_10069 table: FUEL_EXIST
  308. // [HsqlException]は、無視する
  309. // integrity constraint violation: unique constraint or index violation; SYS_PK_10069 table: FUEL_EXIST
  310. // [SQLIntegrityConstraintViolationException]は、無視する
  311. }
  312. }
  313. }
  314. }
  315. static Position getNdPosition(Connection con, String idref) throws SQLException {
  316. PreparedStatement ps8 = con.prepareStatement("SELECT lat,lon FROM AREA_NODE where idref=?");
  317. ps8.setString(1, idref);
  318. try (ResultSet rset8 = ps8.executeQuery()) {
  319. while (rset8.next()) {
  320. Double lat = rset8.getDouble(1);
  321. Double lon = rset8.getDouble(2);
  322. return new Position(lat,lon);
  323. }
  324. }
  325. return null;
  326. }
  327. }