/* javac LandTile.java java LandTile */ import java.io.*; import java.nio.*; import java.util.*; import java.time.*; import java.awt.*; public class LandTile { int cntSrc = 0; int get(int v, int zoom) { return v / (1<<(30-zoom)); } void extract(int x0, int y0, int x1, int y1, int[] xs, int[] ys, int zoomBgn, int zoomEnd, FileWriter[] fws) throws Exception { java.awt.Polygon poly = new java.awt.Polygon(xs, ys, xs.length); if (xs.length>100) System.out.printf("nodes=%d\t", xs.length); for (int zoom = zoomBgn; zoom <= zoomEnd; zoom++) { if (xs.length>100) System.out.printf("%d ", zoom); int fact = 1<<(30-zoom); int xBgn = get(x0, zoom); int xEnd = get(x1, zoom); int yBgn = get(y0, zoom); int yEnd = get(y1, zoom); for (int x = xBgn; x <= xEnd; x++) { for (int y = yBgn; y <= yEnd; y++) { Rectangle rect = new Rectangle(x*fact, y*fact, fact, fact); boolean f = poly.contains(rect); if (f) { String line = x + "," + y + "\n"; fws[zoom-zoomBgn].write(line); } //if (xs.length>100) System.out.printf("%d", f ? 1 : 0); } //if (xs.length>100) System.out.printf("\n"); } } if (xs.length>100) System.out.printf("\n"); } // どちらも含む void extract(int zoomBgn, int zoomEnd, String infile) throws Exception { int bgnX = 215<<(30-8); int bgnY = 91<<(30-8); int endX = 237<<(30-8); int endY = 113<<(30-8); File f = new File(infile); long rest = f.length()/4; // int単位での残りサイズ FileWriter[] fws = new FileWriter[zoomEnd - zoomBgn + 1]; for (int zoom = zoomBgn; zoom <= zoomEnd; zoom++) { String pathout = "c:/osm/landtiles" + zoom + ".csv"; fws[zoom - zoomBgn] = new FileWriter(new File(pathout)); } try (DataInputStream dis = new DataInputStream( new BufferedInputStream(new FileInputStream(infile)))) { while (rest > 0) { cntSrc++; int head = dis.readInt(); rest--; int rec_length = dis.readInt()/4; // int単位に直す rest--; int[] buffer = new int[rec_length]; for (int n = 0; n < buffer.length; n++) { buffer[n] = dis.readInt(); } rest -= rec_length; // レコード全体を読み込み終わった IntBuffer db = IntBuffer.wrap(buffer); int x0 = db.get(); // (1) int y0 = db.get(); // (2) int x1 = db.get(); // (3) int y1 = db.get(); // (4) int rid = db.get(); // (5) rid は使わない int osm_id1 = db.get(); // (6) osm_id int osm_id2 = db.get(); int iway_area = db.get(); // (7) way_area float way_area = Float.intBitsToFloat(iway_area); int key = db.get(); // (10) int val = db.get(); // (11) int num_nodes = db.get(); //if (way_area > 10000000000.0) System.out.printf("%d ", num_nodes); int[] xs = new int[num_nodes]; int[] ys = new int[num_nodes]; for (int i = 0; i < num_nodes; i++) { xs[i] = db.get(); ys[i] = db.get(); } if (x0 > bgnX && y0 > bgnY && x1 < endX && y1 < endY) { extract(x0, y0, x1, y1, xs, ys, zoomBgn, zoomEnd, fws); } } } catch (Exception e) { e.printStackTrace(); } for (int zoom = zoomBgn; zoom <= zoomEnd; zoom++) { fws[zoom-zoomBgn].close(); } } public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); LandTile lt = new LandTile(); lt.extract(8, 10, "c:/osm/lands.dat"); lt.extract(11, 16, "c:/osm/lands_split.dat"); System.out.printf("cntSrc=%d 実行時間=%.2f分\n", lt.cntSrc, (System.currentTimeMillis() - start)/60000.0 ); } }