package osm.jp.api;
import java.net.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
/**
* Java HTTP クライアントサンプル - HttpURLConnection 版 -
*
* @author 68user http://X68000.q-e-d.net/~68user/
*/
public class HttpPOST {
public static String host = "http://overpass-api.de";
public static final String EXIST_FILE = "exist.osm.xml";
public String tableName = null;
public Connection hsqldb = null;
public static void main(String[] args) throws MalformedURLException, ProtocolException, IOException {
double minlat = 35.00d;
double maxlat = 36.00d;
double minlon = 138.00d;
double maxlon = 140.00d;
//getCapabilities(new File("output.xml"), "highway", "bus_stop", minlat, maxlat, minlon, maxlon);
//getCapabilities(new File("output.xml"), "highway", "disused:bus_stop", minlat, maxlat, minlon, maxlon);
//getCapabilities(new File("output.xml"), "amenity", "bus_station", minlat, maxlat, minlon, maxlon);
//getCapabilities(new File("output.xml"), "public_transport", "platform", minlat, maxlat, minlon, maxlon);
//getCapabilities("public_transport", "stop_position", minlat, maxlat, minlon, maxlon, "node");
getCapabilities("amenity", "fuel", minlat, maxlat, minlon, maxlon, "way");
getCapabilities("amenity", "fuel", minlat, maxlat, minlon, maxlon, "node");
}
public HttpPOST(Connection hsqldb, String tableName) {
this.tableName = tableName;
this.hsqldb = hsqldb;
}
/**
* 'HSQLDB.table.OSM_EXIST'を新規に作る
* 'HSQLDB.table.AREA_NODE'を新規に作る
* 既にテーブルが存在する時にはERROR
*
* @throws SQLException
*/
public void create() throws SQLException {
String createSt;
sql("DROP TABLE IF EXISTS "+ this.tableName +" CASCADE");
sql("DROP TABLE IF EXISTS AREA_NODE CASCADE");
// 'table.FUEL_EXIST'を新規に作る
createSt = "CREATE TABLE "+ this.tableName +" (idref VARCHAR(12) NOT NULL, name VARCHAR(128), lat DOUBLE, lon DOUBLE, score INT, PRIMARY KEY(idref));";
Db.updateSQL(hsqldb, createSt);
createSt = "CREATE INDEX "+ this.tableName +"_index ON "+ this.tableName +" (lat, lon);";
Db.updateSQL(hsqldb, createSt);
// 'table.AREA_NODE'を新規に作る
createSt = "CREATE TABLE AREA_NODE (idref VARCHAR(12) NOT NULL, pid VARCHAR(12), lat DOUBLE, lon DOUBLE);";
Db.updateSQL(hsqldb, createSt);
}
public void sql(String sql) throws SQLException {
System.out.println(sql);
try (PreparedStatement ps = this.hsqldb.prepareStatement(sql)) {
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;
}
}
}
public static void getCapabilities(String key, String value, double minLat, double maxLat, double minLon, double maxLon) throws MalformedURLException, ProtocolException, IOException {
getCapabilities(key, value, minLat, maxLat, minLon, maxLon, "node");
}
public static void getCapabilities(String key, String value, double minLat, double maxLat, double minLon, double maxLon, String type) throws MalformedURLException, ProtocolException, IOException {
StringBuilder queryText = new StringBuilder();
queryText.append("<osm-script timeout=\"900\" element-limit=\"1073741824\">");
queryText.append(" <union>");
queryText.append(" <query type=\""+ type +"\">");
queryText.append(" <has-kv k=\""+ key +"\" v=\""+ value +"\"/>");
queryText.append(" <bbox-query s=\"" + minLat + "\" n=\"" + maxLat + "\" w=\"" + minLon + "\" e=\"" + maxLon + "\"/>");
queryText.append(" </query>");
queryText.append(" </union>");
queryText.append(" <print/>");
queryText.append("</osm-script>");
getQuery(queryText.toString());
}
/**
*
* @param queryText クエリテキスト(Overpass_API/Overpass_QL)
* @throws MalformedURLException
* @throws ProtocolException
* @throws IOException
*/
public static void getQuery(String queryText) throws MalformedURLException, ProtocolException, IOException {
System.out.println(host + "/api/interpreter");
URL url = new URL(host + "/api/interpreter");
int responsecode = 0;
do {
HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
try {
urlconn.setRequestMethod("POST");
urlconn.setDoOutput(true); // POSTのデータを後ろに付ける
urlconn.setInstanceFollowRedirects(false); // 勝手にリダイレクトさせない
urlconn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
urlconn.setRequestProperty("Content-Type","text/xml;charset=utf-8");
urlconn.connect();
try (PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(urlconn.getOutputStream(), "utf-8")))) {
outputWriter(pw, queryText);
pw.flush();
}
System.out.println("Sleep 20 sec...");
try {
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {}
responsecode = urlconn.getResponseCode();
System.out.println("レスポンスコード[" + responsecode + "] " +
"レスポンスメッセージ[" + urlconn.getResponseMessage() + "]");
Map<String,List<String>> headers = urlconn.getHeaderFields();
for (Map.Entry<String, List<String>> bar : headers.entrySet()) {
System.out.print("\t" + bar.getKey() +"\t: "); // キーを取得
List<String> vals = bar.getValue(); // 値を取得
for(String str : vals) {
System.out.print("["+ str +"],");
}
System.out.println();
}
if ((responsecode == 429) || (responsecode == 504) || (responsecode == 500)) {
// レスポンスコード[429] レスポンスメッセージ[Too Many Requests]
// レスポンスコード[500] レスポンスメッセージ[Internal server error]
// レスポンスコード[504] レスポンスメッセージ[Gateway Timeout]
System.out.print("Waite 5 minites.");
try {
TimeUnit.MINUTES.sleep(5);
} catch (InterruptedException e) {}
}
else {
System.out.println("\n---- ボディ ----");
File oFile = new File(HttpPOST.EXIST_FILE);
oFile.deleteOnExit();
try (
BufferedWriter hw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(oFile), "UTF-8"));
BufferedReader reader = new BufferedReader(new InputStreamReader(urlconn.getInputStream(), "UTF-8"))
) {
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
hw.write(line);
hw.newLine();
}
hw.flush();
}
}
}
catch (java.net.ConnectException e) {
// レスポンスコード[600] レスポンスメッセージ[接続がタイムアウトしました (Connection timed out)]
responsecode = 600;
}
finally {
urlconn.disconnect();
}
System.out.print("Waite 5 seconds.");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {}
}
while ((responsecode == 429) || (responsecode == 504) || (responsecode == 600));
}
public static void outputWriter(PrintWriter pw, String text) {
System.out.println("\t" + text);
pw.print(text);
}
public static final int POINT_NO = 0; // 評価ポイント無し→ score=50
public static final int POINT_FIXME = 1; // 評価ポイント無し→ score=50
public static final int POINT_BRAND = 2; // 評価ポイント|brand=null → score=1
public static final int POINT_NAME = 4; // 評価ポイント|name=null → score=1
/**
* File(HttpPOST.EXIST_FILE)を読み取って、データベースに反映させる。<br>
* その際に、OSMノードを評価し、scoreを算定する
* param con 反映先のデータベースコネクタ(HSQLDB)
* param point 評価ポイント[POINT_NO|POINT_BRAND|POINT_NAME] 1: 'brand' 2:'name'
*/
/**
*
* @param con
* @param idref
* @return
* @throws SQLException
*/
public static Position getNdPosition(Connection con, String idref) throws SQLException {
PreparedStatement ps8 = con.prepareStatement("SELECT lat,lon FROM AREA_NODE where idref=?");
ps8.setString(1, idref);
try (ResultSet rset8 = ps8.executeQuery()) {
while (rset8.next()) {
Double lat = rset8.getDouble(1);
Double lon = rset8.getDouble(2);
return new Position(lat,lon);
}
}
return null;
}
}