Newer
Older
osmCoverage / src / osm / jp / api / OsmExist.java
@hayashi hayashi on 27 May 2018 9 KB OverpassAPI
package osm.jp.api;

import java.io.*;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

public abstract class OsmExist extends Osmdb {

    /*
    public static void main(String[] args) throws MalformedURLException, ProtocolException, IOException {
        double minlat = 35.13d;
        double maxlat = 35.66d;
        double minlon = 138.99d;
        double maxlon = 139.79d;
        //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");
    }
    */
    
    /*
    Test data:
    ノード: エネオス (2015835273)  場所: 35.4367770, 139.403571TABLE_NAME0
    ノード: ENEOS (1769261234) 場所: 35.4330583, 139.4006876 brand=no
    ノード: 出光 (3877535257) 場所: 45.3985390, 141.6882450 brand=no
    
    select osm_id,amenity,brand,disused,name,
        ST_Y(ST_Transform(way,4326)) as lat,
        ST_X(ST_Transform(way,4326)) as lon
    from planet_osm_point
    where amenity='fuel';
    
    
    ウェイ: 出光 (161877397) ノード
                                1738352013
                                1738351984
                                1738352019
                                1738352024
                                1738352017
                                1738352013
    select osm_id,amenity,brand,name,way_area,
            ST_Astext(ST_Transform(way,4326)) ,
            ST_Y(ST_Transform(ST_Centroid(way),4326)) as lat,
            ST_X(ST_Transform(ST_Centroid(way),4326)) as lon
    from planet_osm_polygon 
    where amenity='fuel';
    
    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))"
    ST_Centroid(way)
    
    */
    /**
     * 
     * <pre>{@code 
     *  (
     *    node[disused:amenity=fuel](35.42,139.39,35.45,139.42);
     *    way[amenity=fuel](35.42,139.39,35.45,139.42);
     *    node[amenity=fuel](35.42,139.39,35.45,139.42);
     *    (way[amenity=fuel](35.42,139.39,35.45,139.42);>;);
     *  );
     *  out;
     * }</pre>
     * 
     * <pre>{@code 
     *  select osm_id,amenity,brand,disused,name from planet_osm_point where amenity='fuel';
     * }</pre>
     *
     * <pre>{@code 
     *  select osm_id,amenity,brand,name,way_area,ST_Astext(ST_Transform(way,4326)) from planet_osm_polygon where amenity='fuel';
     * 
     * 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))"
     * 
     * 
     *  select id,nodes,tags from planet_osm_ways;
     * }</pre>
     * 
     * @param hsqldb
     * @param osmdb
     * @param features
     * @return XML
     * @throws Exception
     */
    /**
     * File(HttpPOST.EXIST_FILE)を読み取って、データベースに反映させる。<br>
     * その際に、OSMノードを評価し、scoreを算定する
     * 
     * @param hsqldb
     * @param features
     * @throws Exception
     */
    public void getJapanCapabilities(Connection hsqldb, ArrayList<Feature> features) throws Exception {
        
        /*
            ```
            (node(changed:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.a;
            (node(newer:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.b;
            (way(changed:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.c;
            (way(newer:"2018-05-20T09:00:00Z")(34.0,138.0,36.0,140.0);)->.d;
            (
             node.a.b["amenity"="fuel"];
             node.a.b["disused:amenity"="fuel"];
             node.a.b["abandoned:amenity"="fuel"];
             node.a.b["demolished:amenity"="fuel"];
             node.a.b["historic:amenity"="fuel"];
             node.a.b["was:amenity"="fuel"];
             node.a.b["removed:amenity"="fuel"];
             node.a.b["no:amenity"="fuel"];
             way.c.d["amenity"="fuel"];
             way.c.d["disused:amenity"="fuel"];
             way.c.d["abandoned:amenity"="fuel"];
             way.c.d["demolished:amenity"="fuel"];
             way.c.d["historic:amenity"="fuel"];
             way.c.d["was:amenity"="fuel"];
             way.c.d["removed:amenity"="fuel"];
             way.c.d["no:amenity"="fuel"];
            );
            out meta;
            ```
        */
        Calendar now = Calendar.getInstance();
        now.add(Calendar.DATE, -7);     // before 1 week
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startDate = sdf.format(now.getTime()) +"T09:00:00Z";
        
        StringBuilder sb = new StringBuilder();
        for (Japan box : Japan.all2) {
            String boxq = String.format("(%d,%d,%d,%d)", box.minLat, box.minLon, box.maxLat, box.maxLon);
            sb.append(String.format("(node(changed:\"%s\")%s;)->.a;\n", startDate, boxq));
            sb.append(String.format("(node(newer:\"%s\")%s;)->.b;\n", startDate, boxq));
            sb.append(String.format("(way(changed:\"%s\")%s;)->.c;\n", startDate, boxq));
            sb.append(String.format("(way(newer:\"%s\")%s;)->.d;\n", startDate, boxq));
            sb.append("(");
            int point = 0;
            for (Feature f : features) {
                if (f.node == Feature.NODE) {
                    sb.append("node.a.b");
                }
                else if (f.node == Feature.AREA) {
                    sb.append("way.c.d");
                }
                sb.append(String.format("[\"%s\"=\"%s\"]\n", f.key, f.v));
                point += f.point;
            }
            sb.append(");\n");
            sb.append("out body;");

            /*--------------------------------------------
                Overpass API を実行して XMLを受信する
            ---------------------------------------------*/
            File xmlFile = HttpPOST.overpassAPI(sb.toString());
            
            
            /*--------------------------------------------
                受信したXMLファイルをパースする
            ---------------------------------------------*/
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(xmlFile);
            Node osmNode = document.getDocumentElement();
            Node itemNodes = osmNode.getFirstChild();
            while(itemNodes != null) {
                String nodeName = itemNodes.getNodeName();
                switch (nodeName) {
                case "node":
                    OsmnodeNode osmnode = new OsmnodeNode(itemNodes);
                    insertExistingNode(hsqldb, osmnode.id, Double.parseDouble(osmnode.latStr), Double.parseDouble(osmnode.lonStr), score(point, osmnode.tags), "");
                    break;
                case "way":
                    break;
                }
                itemNodes = itemNodes.getNextSibling();
            }
        }
        
    }
    
    /**
     * 
     * @param point
     * @param tags
     * @return 
     */
    int score(int point, ArrayList<OsmnodeTag> tags) {
        int score = 50;
        if (tags == null) {
            return 0;
        }
        
        boolean brandYes = false;
        boolean busYes = false;
        boolean fixmeYes = false;
        boolean nameYes = false;
        for (OsmnodeTag tag : tags) {
            if (tag.key.startsWith("fixme")) {
                fixmeYes = true;
            }
            else if (tag.key.equals("bus")) {
                if (tag.value.equals("yes")) {
                    busYes = true;
                }
            }
            else if (tag.key.equals("brand")) {
                brandYes = true;
            }
            else if (tag.key.startsWith("name")) {
                nameYes = true;
            }
        }
        
        if (((point & POINT_NO_BRAND) != 0) && !brandYes) {
            score = 1;
        }
        if (((point & POINT_NO_NAME) != 0) && !nameYes) {
            score = 1;
        }
        if (((point & POINT_FIXME) != 0) && fixmeYes) {
            score = 1;
        }
        if (((point & POINT_BUS_NO) != 0) && !busYes) {
            score = 0;
        }
        return score;
    }
}