Newer
Older
osmCoverage / src / osm / jp / postgis / UnMapped.java
@yuu yuu on 24 Dec 2018 13 KB function: UnMapped.
package osm.jp.postgis;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import javax.xml.parsers.ParserConfigurationException;
import jp.co.areaweb.tools.database.DatabaseTool;
import org.apache.commons.compress.archivers.ArchiveException;
import org.xml.sax.SAXException;
import osm.jp.api.Coverage;
import osm.jp.api.Japan;
import tools.Compless;

public class UnMapped {
    ToPostgis type;
    String dbname;
    
    @SuppressWarnings({"UseSpecificCatch", "CallToPrintStackTrace"})
    public static void main(String[] args) {
        try {
            File kmz = (new UnMapped("busstop"))
                    .getKmz(35.4341254D,139.408969D, 3.0D);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * コンストラクタ
     * @param dbname
     * @throws java.lang.ClassNotFoundException 
     * @throws java.sql.SQLException 
     * @throws java.io.IOException 
     */
    public UnMapped(String dbname) throws ClassNotFoundException, SQLException, IOException {
        this.type = null;
        this.dbname = dbname;
        if (dbname.equals(osm.jp.coverage.busstop.DbBusstop.TABLE_NAME)) {
            this.type = new osm.jp.coverage.busstop.ToPostgis();
        }
        else if (dbname.equals(osm.jp.coverage.fuel.DbFuel.TABLE_NAME)) {
            this.type = new osm.jp.coverage.fuel.ToPostgis();
        }
        else if (dbname.equals(osm.jp.coverage.police.DbPolice.TABLE_NAME)) {
            this.type = new osm.jp.coverage.police.ToPostgis();
        }
        else if (dbname.equals(osm.jp.coverage.postoffice.DbPostoffice.TABLE_NAME)) {
            this.type = new osm.jp.coverage.postoffice.ToPostgis();
        }
    }

    /**
     * 
     * @param lat0  緯度
     * @param lon0  経度
     * @param km    半径(km)
     * @return KMZファイル
     * @throws java.lang.ClassNotFoundException 
     * @throws java.sql.SQLException 
     * @throws java.io.IOException 
     * @throws java.io.FileNotFoundException 
     * @throws javax.xml.parsers.ParserConfigurationException 
     * @throws org.xml.sax.SAXException 
     * @throws org.apache.commons.compress.archivers.ArchiveException 
     */
    public File getKmz(double lat0, double lon0, double km) throws ClassNotFoundException, SQLException, IOException, FileNotFoundException, ParserConfigurationException, SAXException, ArchiveException {
        File kml = new File(dbname +".kml");
        File kmz = new File(dbname +".kmz");
        toKml(kml, "'"+ this.dbname +"' - UnMapped OpenSteetMap", 35.4341254D,139.408969D,3.0D);
        toKmz(kml, kmz);
        kml.delete();
        return kmz;
    }
    
    public UnMapped toKmz(File kml, File kmz) throws ArchiveException, IOException {
        Compless.toZip(kml, kmz);
        return this;
    }
    
    /**
     * 
     * @param kmlFile
     * @param name
     * @param lat0
     * @param lon0
     * @param km
     * @return
     * @throws FileNotFoundException
     * @throws ClassNotFoundException
     * @throws SQLException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws SAXException 
     */
    public UnMapped toKml (File kmlFile, String name, double lat0, double lon0, double km) 
        throws FileNotFoundException, ClassNotFoundException, SQLException, IOException, ParserConfigurationException, SAXException 
    {
        try (Connection conPost = DatabaseTool.openDb(Coverage.DB_PORP_GISDB);
            BufferedWriter ow = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(kmlFile), "UTF-8")))
        {
            ow.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            ow.newLine();
            ow.write("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
            ow.newLine();
            ow.write("<Document>");
            ow.newLine();
            {
                ow.write(getStringStyle());
                ow.newLine();

                ow.write("<name>"+ name +"</name>");
                ow.newLine();
                ow.write("<visibility>1</visibility>");
                ow.newLine();
                ow.write(getStringExtendedData(name));
                ow.newLine();
                
                String sql = "SELECT area,gmlid,fixed,ST_AsGeoJSON(ST_Transform(t_%s.geom,4326))::json As geometry FROM t_%s";
                sql = String.format(sql, type.tableName, type.tableName);
                try (PreparedStatement ps8 = conPost.prepareStatement(sql)) {
                    try (ResultSet rset8 = ps8.executeQuery()) {
                        while (rset8.next()) {
                            String gmlid = rset8.getString("gmlid");
                            int area = rset8.getInt("area");
                            int fixed = rset8.getInt("fixed");

                            // geom: {"type":"Point","coordinates":[143.3147749,42.2984888]}
                            String geom = rset8.getString("geometry");
                            String lonStr = null;
                            String latStr = null;
                            try (JsonReader reader = Json.createReader(new StringReader(geom))) {
                                JsonObject geojson = reader.readObject();
                                JsonArray coordinates = geojson.getJsonArray("coordinates");
                                for (JsonValue v1 : coordinates) {
                                    if (v1.getValueType() == JsonValue.ValueType.NUMBER) {
                                        JsonNumber num = (JsonNumber)v1;
                                        if (lonStr == null) {
                                            lonStr = num.toString();
                                        }
                                        else {
                                            latStr = num.toString();
                                        }
                                    }
                                }
                            }
                            if ((lonStr != null) && (latStr != null)) {
                                double lat = Double.parseDouble(latStr);
                                double lon = Double.parseDouble(lonStr);
                                double dd = Japan.distanceKm(lat0,lon0,lat,lon);
                                if (dd < km) {
                                    String poiname = String.format("%02d - %s", area, gmlid);
                                    String color = decideColor(fixed);
                                    ow.write(getStringPlacemark(poiname, latStr, lonStr, color));
                                    ow.newLine();
                                }
                            }
                        }
                    }
                }
            }
            ow.write("</Document>");
            ow.write("</kml>");
            ow.flush();
        }
        return this;
    }
    
    String decideColor(int fixed) {
        if (this.type instanceof osm.jp.coverage.busstop.ToPostgis) {
            if (fixed == 0) {
                return "red";
            }
            else if (fixed < 100) {
                return "orange";
            }
            else {
                return "green";
            }
        }
        else if (this.type instanceof osm.jp.coverage.fuel.ToPostgis) {
            if (fixed == 0) {
                return "red";
            }
            else if (fixed < 50) {
                return "orange";
            }
            else {
                return "green";
            }
        }
        else if (this.type instanceof osm.jp.coverage.police.ToPostgis) {
            if (fixed == 0) {
                return "red";
            }
            else {
                return "green";
            }
        }
        else if (this.type instanceof osm.jp.coverage.postoffice.ToPostgis) {
            if (fixed == 0) {
                return "red";
            }
            else {
                return "green";
            }
        }
        return "brown";
    }
    
    String getStringStyle() {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append(icon("red"));
        sbuf.append(icon("orange"));
        sbuf.append(icon("green"));
        sbuf.append(icon("brown"));
        return sbuf.toString();
    }
    
    /**
     * 
     * @param color ["red"|"blue"|"purple"|"yellow"|"pink"|"brown"|"green"|"orange"]
     * @return 
     */
    String icon(String color) {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append(String.format("<Style id=\"placemark-%s\">", color));
        sbuf.append("<IconStyle>");
        sbuf.append("<Icon>");
        sbuf.append(String.format("<href>http://maps.me/placemarks/placemark-%s.png</href>", color));
        sbuf.append("</Icon>");
        sbuf.append("</IconStyle>");
        sbuf.append("</Style>");
        return sbuf.toString();
    }
    
    /**
     * 
        <ExtendedData xmlns:mwm="https://maps.me">
          <mwm:name>
            <mwm:lang code="default">poi</mwm:lang>
          </mwm:name>
          <mwm:annotation></mwm:annotation>
          <mwm:description></mwm:description>
          <mwm:lastModified>2018-12-23T01:50:40Z</mwm:lastModified>
          <mwm:accessRules>Local</mwm:accessRules>
        </ExtendedData>
    * 
    * 
    */
    String getStringExtendedData(String name) {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append("<ExtendedData xmlns:mwm=\"https://maps.me\">");
        sbuf.append("<mwm:name><mwm:lang code=\"default\">");
        sbuf.append(name);
        sbuf.append("</mwm:lang></mwm:name>");
        sbuf.append("<mwm:annotation></mwm:annotation>");
        sbuf.append("<mwm:description></mwm:description>");
        
        sbuf.append("<mwm:lastModified>");
        sbuf.append((new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")).format(new Date()));
        sbuf.append("</mwm:lastModified>");
        
        sbuf.append("<mwm:accessRules>Local</mwm:accessRules>");        
        sbuf.append("</ExtendedData>");
        return sbuf.toString();
    }
    
    /**
     * 
        <Placemark>
          <name>新日本海フェリー 苫小牧東港ターミナル</name>
          <TimeStamp><when>2017-12-28T11:15:56Z</when></TimeStamp>
          <styleUrl>#placemark-blue</styleUrl>
          <Point><coordinates>141.81955,42.610008</coordinates></Point>
          <ExtendedData xmlns:mwm="https://maps.me">
            <mwm:name>
              <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
            </mwm:name>
            <mwm:description>
            </mwm:description>
            <mwm:customName>
              <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
            </mwm:customName>
            <mwm:scale>13</mwm:scale>
          </ExtendedData>
        </Placemark>
     * 
     */
    String getStringPlacemark(String name, String latStr, String lonStr, String color) {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append("<Placemark>");
        sbuf.append("<name>");
        sbuf.append(name);
        sbuf.append("</name>");
        sbuf.append("<TimeStamp><when>");
        sbuf.append((new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")).format(new Date()));
        sbuf.append("</when></TimeStamp>");
        sbuf.append(String.format("<styleUrl>#placemark-%s</styleUrl>", color));
        sbuf.append("<Point><coordinates>");
        sbuf.append(String.format("%s,%s", lonStr, latStr));
        sbuf.append("</coordinates></Point>");
        sbuf.append(getStringPlacemarkExtendedData(name));
        sbuf.append("</Placemark>");
        return sbuf.toString();
    }
    
    /**
     * 
        <ExtendedData xmlns:mwm="https://maps.me">
          <mwm:name>
            <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
          </mwm:name>
          <mwm:description>
          </mwm:description>
          <mwm:customName>
            <mwm:lang code="default">新日本海フェリー 苫小牧東港ターミナル</mwm:lang>
          </mwm:customName>
          <mwm:scale>13</mwm:scale>
        </ExtendedData>
    * 
    */
    String getStringPlacemarkExtendedData(String name) {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append("<ExtendedData xmlns:mwm=\"https://maps.me\">");
        sbuf.append("<mwm:name><mwm:lang code=\"default\">");
        sbuf.append(name);
        sbuf.append("</mwm:lang></mwm:name>");
        sbuf.append("<mwm:description></mwm:description>");
        sbuf.append("<mwm:customName><mwm:lang code=\"default\">");
        sbuf.append(name);
        sbuf.append("</mwm:lang></mwm:customName>");
        sbuf.append("<mwm:scale>13</mwm:scale>");
        sbuf.append("</ExtendedData>");
        return sbuf.toString();
    }
    
}