AscReaderDriver { public void read(Connection connection, InputStream inputStream, ProgressVisitor progress, String tableReference, int srid) throws SQLException, IOException { BufferedInputStream bof = new BufferedInputStream(inputStream, BUFFER_SIZE); String lastWord = ""; try { Scanner scanner = new Scanner(bof); lastWord = scanner.next(); if (!lastWord.equalsIgnoreCase("NCOLS")) { throw new IOException("Unexpected word " + lastWord); } lastWord = scanner.next(); int ncols = Integer.parseInt(lastWord); if (ncols <= 0) { throw new IOException("NCOLS <= 0"); } lastWord = scanner.next(); if (!lastWord.equalsIgnoreCase("NROWS")) { throw new IOException("Unexpected word " + lastWord); } lastWord = scanner.next(); int nrows = Integer.parseInt(lastWord); if (nrows <= 0) { throw new IOException("NROWS <= 0"); } lastWord = scanner.next(); if (!(lastWord.equalsIgnoreCase("XLLCENTER") || lastWord.equalsIgnoreCase("XLLCORNER"))) { throw new IOException("Unexpected word " + lastWord); } boolean isXCenter = lastWord.equalsIgnoreCase("XLLCENTER"); lastWord = scanner.next(); double xValue = Double.parseDouble(lastWord); lastWord = scanner.next(); if (!(lastWord.equalsIgnoreCase("YLLCENTER") || lastWord.equalsIgnoreCase("YLLCORNER"))) { throw new IOException("Unexpected word " + lastWord); } boolean isYCenter = lastWord.equalsIgnoreCase("YLLCENTER"); lastWord = scanner.next(); double yValue = Double.parseDouble(lastWord); lastWord = scanner.next(); if (!lastWord.equalsIgnoreCase("CELLSIZE")) { throw new IOException("Unexpected word " + lastWord); } lastWord = scanner.next(); double cellSize = Double.parseDouble(lastWord); if (isXCenter) { xValue = xValue - cellSize / 2; } if (isYCenter) { yValue = yValue + cellSize * nrows - cellSize / 2; } else { yValue = yValue + cellSize * nrows; } lastWord = scanner.next(); boolean readFirst = false; int noData = -9999; if (lastWord.equalsIgnoreCase("NODATA_VALUE")) { readFirst = true; lastWord = scanner.next(); noData = Integer.parseInt(lastWord); } Statement st = connection.createStatement(); PreparedStatement preparedStatement; if(as3DPoint) { st.execute("CREATE TABLE " + tableReference + "(PK SERIAL NOT NULL, THE_GEOM GEOMETRY, " + " CONSTRAINT ASC_PK PRIMARY KEY (PK))"); preparedStatement = connection.prepareStatement("INSERT INTO " + tableReference + "(the_geom) VALUES (?)"); } else { st.execute("CREATE TABLE " + tableReference + "(PK SERIAL NOT NULL, THE_GEOM GEOMETRY,Z int, " + " CONSTRAINT ASC_PK PRIMARY KEY (PK))"); preparedStatement = connection.prepareStatement("INSERT INTO " + tableReference + "(the_geom, Z) VALUES (?, ?)"); } GeometryFactory factory = new GeometryFactory(); int batchSize = 0; int firstRow = 0; int firstCol = 0; int lastRow = nrows; int lastCol = ncols; if(extractEnvelope != null) { firstCol = (int)Math.floor((extractEnvelope.getMinX() - xValue) / cellSize); lastCol = (int)Math.ceil((extractEnvelope.getMaxX() - xValue) / cellSize); firstRow = nrows - (int)Math.ceil((extractEnvelope.getMaxY() - (yValue - cellSize * nrows)) / cellSize); lastRow = nrows - (int)Math.ceil((extractEnvelope.getMinY() - (yValue - cellSize * nrows)) / cellSize); } ProgressVisitor cellProgress = new EmptyProgressVisitor(); if (progress != null) { cellProgress = progress.subProcess(lastRow); } for (int i = 0; i < nrows; i++) { for (int j = 0; j < ncols; j++) { if (readFirst) { lastWord = scanner.next(); } else { readFirst = true; } if((downScale == 1 || (i % downScale == 0 && j % downScale == 0)) && (extractEnvelope == null || (i >= firstRow && i <= lastRow && j >= firstCol && j <= lastCol))) { int data = Integer.parseInt(lastWord); double x = xValue + j * cellSize; double y = yValue - i * cellSize; if (as3DPoint) { if (data != noData) { Point cell = factory.createPoint(new Coordinate(new Coordinate(x + cellSize / 2, y - cellSize / 2, data))); cell.setSRID(srid); preparedStatement.setObject(1, cell); preparedStatement.addBatch(); batchSize++; } } else { Polygon cell = factory.createPolygon(new Coordinate[]{new Coordinate(x, y), new Coordinate(x, y - cellSize * downScale), new Coordinate(x + cellSize * downScale, y - cellSize * downScale), new Coordinate(x + cellSize * downScale, y), new Coordinate(x, y)}); cell.setSRID(srid); preparedStatement.setObject(1, cell); if (data != noData) { preparedStatement.setObject(2, data); } else { preparedStatement.setNull(2, Types.INTEGER); } preparedStatement.addBatch(); batchSize++; } if (batchSize >= BATCH_MAX_SIZE) { preparedStatement.executeBatch(); preparedStatement.clearBatch(); batchSize = 0; } } } cellProgress.endStep(); if(i > lastRow) { break; } } if (batchSize > 0) { preparedStatement.executeBatch(); } } catch (NoSuchElementException | NumberFormatException ex) { throw new SQLException("Unexpected word " + lastWord, ex); } }  boolean isAs3DPoint(); void setAs3DPoint(boolean as3DPoint); Envelope getExtractEnvelope(); void setExtractEnvelope(Envelope extractEnvelope); int getDownScale(); void setDownScale(int downScale); void read(Connection connection, InputStream inputStream, ProgressVisitor progress, String tableReference,
                     int srid);  }
@Test public void testReadPrecip() throws IOException, SQLException { AscReaderDriver reader = new AscReaderDriver(); try(InputStream inputStream = AscReaderDriverTest.class.getResourceAsStream("precip30min.asc")) { reader.read(connection, inputStream, new EmptyProgressVisitor(), "PRECIP30MIN", 4326); } Statement st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-179.74,-80.18))")) { assertTrue(rs.next()); assertEquals(234, rs.getInt("Z")); } st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-172.604,-89.867))")) { assertTrue(rs.next()); assertEquals(114, rs.getInt("Z")); } st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-177.438, -84.077))")) { assertTrue(rs.next()); assertNull(rs.getObject("Z")); } }
@Test public void testReadPrecipCenter() throws IOException, SQLException { AscReaderDriver reader = new AscReaderDriver(); try(InputStream inputStream = AscReaderDriverTest.class.getResourceAsStream("precip30min_center.asc")) { reader.read(connection, inputStream, new EmptyProgressVisitor(), "PRECIP30MIN", 4326); } Statement st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-180.1454, -80.303))")) { assertTrue(rs.next()); assertEquals(234, rs.getInt("Z")); } st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-173.213, -89.771))")) { assertTrue(rs.next()); assertEquals(114, rs.getInt("Z")); } st = connection.createStatement(); try(ResultSet rs = st.executeQuery("SELECT * FROM PRECIP30MIN WHERE ST_INTERSECTS(THE_GEOM, ST_MAKEPOINT(-177.3831, -84.5793))")) { assertTrue(rs.next()); assertNull(rs.getObject("Z")); } }