Newer
Older
osmCoverage / src / osm / jp / api / OsmExist.java
@hayashi hayashi on 5 Jun 2018 9 KB xxx
  1. package osm.jp.api;
  2.  
  3. import java.io.*;
  4. import java.sql.Connection;
  5. import java.text.SimpleDateFormat;
  6. import java.util.ArrayList;
  7. import java.util.Calendar;
  8. import javax.xml.parsers.DocumentBuilder;
  9. import javax.xml.parsers.DocumentBuilderFactory;
  10. import org.w3c.dom.Document;
  11. import org.w3c.dom.Node;
  12.  
  13. public abstract class OsmExist extends Osmdb {
  14. public ArrayList<OsmnodeNode> nodelist = new ArrayList<>();
  15.  
  16.  
  17. public OsmExist(Connection hsqldb, String tableName) {
  18. super(hsqldb, tableName);
  19. }
  20. /*
  21. Test data:
  22. ノード: エネオス (2015835273) 場所: 35.4367770, 139.403571TABLE_NAME0
  23. ノード: ENEOS (1769261234) 場所: 35.4330583, 139.4006876 brand=no
  24. ノード: 出光 (3877535257) 場所: 45.3985390, 141.6882450 brand=no
  25. select osm_id,amenity,brand,disused,name,
  26. ST_Y(ST_Transform(way,4326)) as lat,
  27. ST_X(ST_Transform(way,4326)) as lon
  28. from planet_osm_point
  29. where amenity='fuel';
  30. ウェイ: 出光 (161877397) ノード
  31. 1738352013
  32. 1738351984
  33. 1738352019
  34. 1738352024
  35. 1738352017
  36. 1738352013
  37. select osm_id,amenity,brand,name,way_area,
  38. ST_Astext(ST_Transform(way,4326)) ,
  39. ST_Y(ST_Transform(ST_Centroid(way),4326)) as lat,
  40. ST_X(ST_Transform(ST_Centroid(way),4326)) as lon
  41. from planet_osm_polygon
  42. where amenity='fuel';
  43. 161877397;"fuel";"出光";"出光";1415.14;"POLYGON((139.402982078119 35.4372453832977,139.403208992559 35.4373490207424,139.4033330499 35.4371591650393,139.403407160911 35.4370741177365,139.403148446109 35.4369273706731,139.402982078119 35.4372453832977))"
  44. ST_Centroid(way)
  45. */
  46. /**
  47. *
  48. * <pre>{@code
  49. * (
  50. * node[disused:amenity=fuel](35.42,139.39,35.45,139.42);
  51. * way[amenity=fuel](35.42,139.39,35.45,139.42);
  52. * node[amenity=fuel](35.42,139.39,35.45,139.42);
  53. * (way[amenity=fuel](35.42,139.39,35.45,139.42);>;);
  54. * );
  55. * out;
  56. * }</pre>
  57. *
  58. * <pre>{@code
  59. * select osm_id,amenity,brand,disused,name from planet_osm_point where amenity='fuel';
  60. * }</pre>
  61. *
  62. * <pre>{@code
  63. * select osm_id,amenity,brand,name,way_area,ST_Astext(ST_Transform(way,4326)) from planet_osm_polygon where amenity='fuel';
  64. *
  65. * 168977587;"fuel";"JA";"兼城SS";1378;"POLYGON((127.692529751123 26.1483225993078,127.692852156479 26.1482644594179,127.692800683013 26.1478020809547,127.692690280065 26.1478324815483,127.692623984397 26.1480452048431,127.692529751123 26.1483225993078))"
  66. *
  67. *
  68. * select id,nodes,tags from planet_osm_ways;
  69. * }</pre>
  70. *
  71. * @param hsqldb
  72. * @param osmdb
  73. * @param features
  74. * @return XML
  75. * @throws Exception
  76. */
  77. /**
  78. * File(HttpPOST.EXIST_FILE)を読み取って、データベースに反映させる。<br>
  79. * その際に、OSMノードを評価し、scoreを算定する
  80. *
  81. * @param features
  82. * @param boxes
  83. * @throws Exception
  84. */
  85. public void getJapanCapabilities(ArrayList<Feature> features, Japan[] boxes) throws Exception {
  86. /*
  87. ```
  88. (node(changed:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.a;
  89. (node(newer:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.b;
  90. (way(changed:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.c;
  91. (way(newer:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.d;
  92. (
  93. node.a.b["amenity"="fuel"];
  94. node.a.b["disused:amenity"="fuel"];
  95. node.a.b["abandoned:amenity"="fuel"];
  96. node.a.b["demolished:amenity"="fuel"];
  97. node.a.b["historic:amenity"="fuel"];
  98. node.a.b["was:amenity"="fuel"];
  99. node.a.b["removed:amenity"="fuel"];
  100. node.a.b["no:amenity"="fuel"];
  101. way.c.d["amenity"="fuel"];
  102. way.c.d["disused:amenity"="fuel"];
  103. way.c.d["abandoned:amenity"="fuel"];
  104. way.c.d["demolished:amenity"="fuel"];
  105. way.c.d["historic:amenity"="fuel"];
  106. way.c.d["was:amenity"="fuel"];
  107. way.c.d["removed:amenity"="fuel"];
  108. way.c.d["no:amenity"="fuel"];
  109. );
  110. (._;>;);
  111. out meta;
  112. ```
  113. */
  114. Calendar now = Calendar.getInstance();
  115. now.add(Calendar.DATE, -7); // before 1 week
  116. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  117. String startDate = sdf.format(now.getTime()) +"T09:00:00Z";
  118. StringBuilder sb = new StringBuilder();
  119. for (Japan box : boxes) {
  120. String boxq = String.format("(%2.1f,%3.1f,%2.1f,%3.1f)", box.minLat, box.minLon, box.maxLat, box.maxLon);
  121. sb.append(String.format("(node(changed:\"%s\")%s;)->.a;\n", startDate, boxq));
  122. sb.append(String.format("(node(newer:\"%s\")%s;)->.b;\n", startDate, boxq));
  123. sb.append(String.format("(way(changed:\"%s\")%s;)->.c;\n", startDate, boxq));
  124. sb.append(String.format("(way(newer:\"%s\")%s;)->.d;\n", startDate, boxq));
  125. sb.append("(");
  126. int point = 0;
  127. for (Feature f : features) {
  128. if (f.node == Feature.NODE) {
  129. sb.append("node.a.b");
  130. }
  131. else if (f.node == Feature.AREA) {
  132. sb.append("way.c.d");
  133. }
  134. sb.append(String.format("[\"%s\"=\"%s\"];\n", f.key, f.v));
  135. point += f.point;
  136. }
  137. sb.append(");\n");
  138. sb.append("(._;>;);\n");
  139. sb.append("out body;");
  140.  
  141. /*--------------------------------------------
  142. Overpass API を実行して XMLを受信する
  143. ---------------------------------------------*/
  144. HttpPOST.getQuery(sb.toString());
  145. File xmlFile = new File(HttpPOST.EXIST_FILE);
  146.  
  147. /*--------------------------------------------
  148. 受信したXMLファイルをパースする
  149. ---------------------------------------------*/
  150. DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
  151. DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
  152. Document document = documentBuilder.parse(xmlFile);
  153. Node osmNode = document.getDocumentElement();
  154. Node itemNodes = osmNode.getFirstChild();
  155. while(itemNodes != null) {
  156. String nodeName = itemNodes.getNodeName();
  157. switch (nodeName) {
  158. case "node":
  159. OsmnodeNode osmnode = new OsmnodeNode(itemNodes);
  160. nodelist.add(osmnode);
  161. if (osmnode.tags.size() > 0) {
  162. insertExistingNode(osmnode.id, Double.parseDouble(osmnode.latStr), Double.parseDouble(osmnode.lonStr), score(point, osmnode.tags), "", osmnode.isRemoved());
  163. }
  164. break;
  165. case "way":
  166. OsmnodeArea osmway = new OsmnodeArea(itemNodes);
  167. osmway.setPosition(nodelist);
  168. if (osmway.tags.size() > 0) {
  169. insertExistingNode(osmway.id, Double.parseDouble(osmway.latStr), Double.parseDouble(osmway.lonStr), score(point, osmway.tags), "", osmway.isRemoved());
  170. }
  171. break;
  172. }
  173. itemNodes = itemNodes.getNextSibling();
  174. }
  175. }
  176. }
  177. /**
  178. *
  179. * @param point
  180. * @param tags
  181. * @return
  182. */
  183. int score(int point, ArrayList<OsmnodeTag> tags) {
  184. int score = 50;
  185. if (tags == null) {
  186. return 0;
  187. }
  188. boolean brandYes = false;
  189. boolean busYes = false;
  190. boolean fixmeYes = false;
  191. boolean nameYes = false;
  192. for (OsmnodeTag tag : tags) {
  193. if (tag.key.startsWith("fixme")) {
  194. fixmeYes = true;
  195. }
  196. else if (tag.key.equals("bus")) {
  197. if (tag.value.equals("yes")) {
  198. busYes = true;
  199. }
  200. }
  201. else if (tag.key.equals("brand")) {
  202. brandYes = true;
  203. }
  204. else if (tag.key.startsWith("name")) {
  205. nameYes = true;
  206. }
  207. }
  208. if (((point & POINT_NO_BRAND) != 0) && !brandYes) {
  209. score = 1;
  210. }
  211. if (((point & POINT_NO_NAME) != 0) && !nameYes) {
  212. score = 1;
  213. }
  214. if (((point & POINT_FIXME) != 0) && fixmeYes) {
  215. score = 1;
  216. }
  217. if (((point & POINT_BUS_NO) != 0) && !busYes) {
  218. score = 0;
  219. }
  220. return score;
  221. }
  222. }