Newer
Older
osmCoverage / src / osm / jp / postgis / Kml.java
  1. package osm.jp.postgis;
  2.  
  3. import java.io.BufferedWriter;
  4. import java.io.IOException;
  5. import java.io.PipedWriter;
  6. import java.io.PrintWriter;
  7. import java.io.StringReader;
  8. import java.sql.Connection;
  9. import java.sql.PreparedStatement;
  10. import java.sql.ResultSet;
  11. import java.text.SimpleDateFormat;
  12. import java.util.Date;
  13. import javax.json.Json;
  14. import javax.json.JsonArray;
  15. import javax.json.JsonNumber;
  16. import javax.json.JsonObject;
  17. import javax.json.JsonReader;
  18. import javax.json.JsonValue;
  19. import jp.co.areaweb.tools.database.DatabaseTool;
  20. import osm.jp.api.Coverage;
  21. import osm.jp.api.Japan;
  22. import osm.jp.api.RectArea;
  23.  
  24. public class Kml implements Runnable {
  25. private ToPostgis type;
  26. private final String name;
  27. private final double lat;
  28. private final double lon;
  29. private final double km;
  30. PipedWriter pipeOut;
  31.  
  32. public static final int MAX_DATA_COUNT = 1000;
  33.  
  34. /**
  35. *
  36. * @param pipeOut
  37. * @param dbname
  38. * @param name
  39. * @param lat
  40. * @param lon
  41. * @param km
  42. * @throws java.io.IOException
  43. */
  44. public Kml(PipedWriter pipeOut, String dbname, String name, double lat, double lon, double km) throws IOException {
  45. this.name = name;
  46. this.lat = lat;
  47. this.lon = lon;
  48. this.km = km;
  49. this.type = null;
  50. if (dbname.equals(osm.jp.coverage.busstop.DbBusstop.TABLE_NAME)) {
  51. this.type = new osm.jp.coverage.busstop.ToPostgis();
  52. }
  53. else if (dbname.equals(osm.jp.coverage.fuel.DbFuel.TABLE_NAME)) {
  54. this.type = new osm.jp.coverage.fuel.ToPostgis();
  55. }
  56. else if (dbname.equals(osm.jp.coverage.police.DbPolice.TABLE_NAME)) {
  57. this.type = new osm.jp.coverage.police.ToPostgis();
  58. }
  59. else if (dbname.equals(osm.jp.coverage.postoffice.DbPostoffice.TABLE_NAME)) {
  60. this.type = new osm.jp.coverage.postoffice.ToPostgis();
  61. }
  62. this.pipeOut = pipeOut;
  63. }
  64.  
  65. @Override
  66. @SuppressWarnings({"CallToPrintStackTrace", "SleepWhileInLoop"})
  67. public void run() {
  68. BufferedWriter bw = new BufferedWriter(pipeOut);
  69. try (PrintWriter ow = new PrintWriter(bw))
  70. {
  71. ow.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  72. ow.println("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
  73. ow.println("<Document>");
  74. ow.flush();
  75. try {
  76. Thread.sleep(0);
  77. }
  78. catch (InterruptedException ex) {
  79. ex.printStackTrace();
  80. }
  81. int count = 0;
  82. try (Connection conPost = DatabaseTool.openDb(Coverage.DB_PORP_GISDB))
  83. {
  84. ow.println(getStringStyle());
  85. ow.println("<name>"+ name +"</name>");
  86. ow.println("<visibility>1</visibility>");
  87. ow.println(getStringExtendedData(name));
  88. ow.flush();
  89. try {
  90. Thread.sleep(0);
  91. }
  92. catch(InterruptedException ex) {
  93. ex.printStackTrace();
  94. }
  95. String sql = "SELECT area,gmlid,fixed,ST_Y(geom) AS lat, ST_X(geom) AS lon, ST_AsGeoJSON(ST_Transform(t_%s.geom,4326))::json As geometry "
  96. + "FROM t_%s "
  97. + "WHERE (ST_Y(geom) > ?) and (ST_Y(geom) < ?) and (ST_X(geom) > ?) and (ST_X(geom) < ?)";
  98. sql = String.format(sql, type.tableName, type.tableName);
  99. try (PreparedStatement ps8 = conPost.prepareStatement(sql)) {
  100. RectArea rect = new RectArea(lat, lon, (int)(km * 2000));
  101. ps8.setDouble(1, rect.minlat);
  102. ps8.setDouble(2, rect.maxlat);
  103. ps8.setDouble(3, rect.minlon);
  104. ps8.setDouble(4, rect.maxlon);
  105. try (ResultSet rset8 = ps8.executeQuery()) {
  106. while (rset8.next()) {
  107. String gmlid = rset8.getString("gmlid");
  108. int area = rset8.getInt("area");
  109. int fixed = rset8.getInt("fixed");
  110. // geom: {"type":"Point","coordinates":[143.3147749,42.2984888]}
  111. String geom = rset8.getString("geometry");
  112. String lonStr = null;
  113. String latStr = null;
  114. try (JsonReader reader = Json.createReader(new StringReader(geom))) {
  115. JsonObject geojson = reader.readObject();
  116. JsonArray coordinates = geojson.getJsonArray("coordinates");
  117. for (JsonValue v1 : coordinates) {
  118. if (v1.getValueType() == JsonValue.ValueType.NUMBER) {
  119. JsonNumber num = (JsonNumber)v1;
  120. if (lonStr == null) {
  121. lonStr = num.toString();
  122. }
  123. else {
  124. latStr = num.toString();
  125. }
  126. }
  127. }
  128. }
  129. if ((lonStr != null) && (latStr != null)) {
  130. double lat0 = Double.parseDouble(latStr);
  131. double lon0 = Double.parseDouble(lonStr);
  132. double dd = Japan.distanceKm(lat,lon,lat0,lon0);
  133. if (dd < km) {
  134. count++;
  135. if (count <= MAX_DATA_COUNT) {
  136. String poiname = String.format("%02d - %s", area, gmlid);
  137. String color = decideColor(fixed);
  138. String str = getStringPlacemark(poiname, latStr, lonStr, color);
  139. ow.println(str);
  140. ow.flush();
  141. try {
  142. Thread.sleep(0);
  143. }
  144. catch(InterruptedException ex) {
  145. ex.printStackTrace();
  146. }
  147. }
  148. else {
  149. break;
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. ow.println("</Document>");
  158. ow.println("</kml>");
  159. ow.flush();
  160. }
  161. catch (Exception ex) {
  162. ex.printStackTrace();
  163. }
  164. }
  165. String decideColor(int fixed) {
  166. if (this.type instanceof osm.jp.coverage.busstop.ToPostgis) {
  167. if (fixed == 0) {
  168. return "red";
  169. }
  170. else if (fixed < 100) {
  171. return "orange";
  172. }
  173. else {
  174. return "green";
  175. }
  176. }
  177. else if (this.type instanceof osm.jp.coverage.fuel.ToPostgis) {
  178. if (fixed == 0) {
  179. return "red";
  180. }
  181. else if (fixed < 50) {
  182. return "orange";
  183. }
  184. else {
  185. return "green";
  186. }
  187. }
  188. else if (this.type instanceof osm.jp.coverage.police.ToPostgis) {
  189. if (fixed == 0) {
  190. return "red";
  191. }
  192. else {
  193. return "green";
  194. }
  195. }
  196. else if (this.type instanceof osm.jp.coverage.postoffice.ToPostgis) {
  197. if (fixed == 0) {
  198. return "red";
  199. }
  200. else {
  201. return "green";
  202. }
  203. }
  204. return "brown";
  205. }
  206. String getStringStyle() {
  207. StringBuilder sbuf = new StringBuilder();
  208. sbuf.append(icon("red"));
  209. sbuf.append(icon("orange"));
  210. sbuf.append(icon("green"));
  211. sbuf.append(icon("brown"));
  212. return sbuf.toString();
  213. }
  214. /**
  215. *
  216. * @param color ["red"|"blue"|"purple"|"yellow"|"pink"|"brown"|"green"|"orange"]
  217. * @return
  218. */
  219. String icon(String color) {
  220. StringBuilder sbuf = new StringBuilder();
  221. sbuf.append(String.format("<Style id=\"placemark-%s\">", color));
  222. sbuf.append("<IconStyle>");
  223. sbuf.append("<Icon>");
  224. sbuf.append(String.format("<href>http://maps.me/placemarks/placemark-%s.png</href>", color));
  225. sbuf.append("</Icon>");
  226. sbuf.append("</IconStyle>");
  227. sbuf.append("</Style>");
  228. return sbuf.toString();
  229. }
  230. /**
  231. *
  232. <ExtendedData xmlns:mwm="https://maps.me">
  233. <mwm:name>
  234. <mwm:lang code="default">poi</mwm:lang>
  235. </mwm:name>
  236. <mwm:annotation></mwm:annotation>
  237. <mwm:description></mwm:description>
  238. <mwm:lastModified>2018-12-23T01:50:40Z</mwm:lastModified>
  239. <mwm:accessRules>Local</mwm:accessRules>
  240. </ExtendedData>
  241. *
  242. *
  243. */
  244. String getStringExtendedData(String name) {
  245. StringBuilder sbuf = new StringBuilder();
  246. sbuf.append("<ExtendedData xmlns:mwm=\"https://maps.me\">");
  247. sbuf.append("<mwm:name><mwm:lang code=\"default\">");
  248. sbuf.append(name);
  249. sbuf.append("</mwm:lang></mwm:name>");
  250. sbuf.append("<mwm:annotation></mwm:annotation>");
  251. sbuf.append("<mwm:description></mwm:description>");
  252. sbuf.append("<mwm:lastModified>");
  253. sbuf.append((new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")).format(new Date()));
  254. sbuf.append("</mwm:lastModified>");
  255. sbuf.append("<mwm:accessRules>Local</mwm:accessRules>");
  256. sbuf.append("</ExtendedData>");
  257. return sbuf.toString();
  258. }
  259. /**
  260. *
  261. <Placemark>
  262. <name>新日本海フェリー 苫小牧東港ターミナル</name>
  263. <TimeStamp><when>2017-12-28T11:15:56Z</when></TimeStamp>
  264. <styleUrl>#placemark-blue</styleUrl>
  265. <Point><coordinates>141.81955,42.610008</coordinates></Point>
  266. <ExtendedData xmlns:mwm="https://maps.me">
  267. <mwm:name>
  268. <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
  269. </mwm:name>
  270. <mwm:description>
  271. </mwm:description>
  272. <mwm:customName>
  273. <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
  274. </mwm:customName>
  275. <mwm:scale>13</mwm:scale>
  276. </ExtendedData>
  277. </Placemark>
  278. *
  279. */
  280. String getStringPlacemark(String name, String latStr, String lonStr, String color) {
  281. StringBuilder sbuf = new StringBuilder();
  282. sbuf.append("<Placemark>");
  283. sbuf.append("<name>");
  284. sbuf.append(name);
  285. sbuf.append("</name>");
  286. sbuf.append("<TimeStamp><when>");
  287. sbuf.append((new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")).format(new Date()));
  288. sbuf.append("</when></TimeStamp>");
  289. sbuf.append(String.format("<styleUrl>#placemark-%s</styleUrl>", color));
  290. sbuf.append("<Point><coordinates>");
  291. sbuf.append(String.format("%s,%s", lonStr, latStr));
  292. sbuf.append("</coordinates></Point>");
  293. sbuf.append(getStringPlacemarkExtendedData(name));
  294. sbuf.append("</Placemark>");
  295. return sbuf.toString();
  296. }
  297. /**
  298. *
  299. <ExtendedData xmlns:mwm="https://maps.me">
  300. <mwm:name>
  301. <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
  302. </mwm:name>
  303. <mwm:description>
  304. </mwm:description>
  305. <mwm:customName>
  306. <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
  307. </mwm:customName>
  308. <mwm:scale>13</mwm:scale>
  309. </ExtendedData>
  310. *
  311. */
  312. String getStringPlacemarkExtendedData(String name) {
  313. StringBuilder sbuf = new StringBuilder();
  314. sbuf.append("<ExtendedData xmlns:mwm=\"https://maps.me\">");
  315. sbuf.append("<mwm:name><mwm:lang code=\"default\">");
  316. sbuf.append(name);
  317. sbuf.append("</mwm:lang></mwm:name>");
  318. sbuf.append("<mwm:description></mwm:description>");
  319. sbuf.append("<mwm:customName><mwm:lang code=\"default\">");
  320. sbuf.append(name);
  321. sbuf.append("</mwm:lang></mwm:customName>");
  322. sbuf.append("<mwm:scale>13</mwm:scale>");
  323. sbuf.append("</ExtendedData>");
  324. return sbuf.toString();
  325. }
  326. }