/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#getGridSelectStatement(org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo) */ @Override protected String getGridSelectStatement(ImageLevelInfo li) { if (li.isImplementedAsTableSplit()) { return MessageFormat.format( gridSelectJoined, new Object[] {li.getSpatialTableName(), li.getTileTableName()}); } else { return MessageFormat.format(gridSelect, new Object[] {li.getSpatialTableName()}); } }
/** * @param li ImageLevelInfo object * @param con JDBC Connection * @return the resolution for li, based on a random chosen tile * @throws SQLException * @throws IOException */ protected double[] getPixelResolution(ImageLevelInfo li, Connection con) throws SQLException, IOException { double[] result = null; String statementString = getRandomTileStatement(li); PreparedStatement s = con.prepareStatement(statementString); ResultSet r = s.executeQuery(); while (r.next()) { byte[] tileBytes = getTileBytes(r); if (tileBytes == null) { continue; } BufferedImage buffImage = null; li.setCanImageIOReadFromInputStream(true); try { buffImage = ImageIO.read(new ByteArrayInputStream(tileBytes)); } catch (IOException e) { } if (buffImage == null) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning( "Image IO cannot read from ByteInputStream,use less efficient jai methods"); } li.setCanImageIOReadFromInputStream(false); SeekableStream stream = new ByteArraySeekableStream(tileBytes); String decoderName = null; for (String dn : ImageCodec.getDecoderNames(stream)) { decoderName = dn; break; } ImageDecoder decoder = ImageCodec.createImageDecoder(decoderName, stream, null); PlanarImage img = PlanarImage.wrapRenderedImage(decoder.decodeAsRenderedImage()); buffImage = img.getAsBufferedImage(); } Envelope env = getEnvelopeFromResultSet(r); result = new double[] { env.getWidth() / buffImage.getWidth(), env.getHeight() / buffImage.getHeight() }; break; } r.close(); s.close(); return result; }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#getExtent(org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo, * java.sql.Connection) */ @Override protected Envelope getExtent(ImageLevelInfo li, Connection con) throws SQLException, IOException { String extentSelect = getExtentSelectStatment(li); String statementString = MessageFormat.format(extentSelect, new Object[] {li.getSpatialTableName()}); Envelope extent = null; PreparedStatement s = con.prepareStatement(statementString); ResultSet r = s.executeQuery(); if (r.next()) { Object o = r.getObject(1); String pgString = o.toString(); int start = pgString.indexOf("(") + 1; int end = pgString.indexOf(")"); pgString = pgString.substring(start, end); String[] coords = pgString.split(","); String[] lower = coords[0].split(" "); String[] upper = coords[1].split(" "); extent = new Envelope( new Coordinate(new Double(lower[0]), new Double(lower[1])), new Coordinate(new Double(upper[0]), new Double(upper[1]))); } r.close(); s.close(); return extent; }
public int compareTo(ImageLevelInfo other) { int res = 0; if ((res = getCoverageName().compareTo(other.getCoverageName())) != 0) { return res; } if ((res = getResX().compareTo(other.getResX())) != 0) { return res; } if ((res = getResY().compareTo(other.getResY())) != 0) { return res; } return 0; }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#setGridSelectParams(java.sql.PreparedStatement, * org.geotools.geometry.GeneralEnvelope, org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo) */ @Override protected void setGridSelectParams( PreparedStatement s, GeneralEnvelope envelope, ImageLevelInfo li) throws SQLException { WKBWriter w = new WKBWriter(); byte[] bytes = w.write(polyFromEnvelope(envelope)); s.setBytes(1, bytes); s.setInt(2, li.getSrsId()); }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#getSRSID(org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo, * java.sql.Connection) */ @Override protected Integer getSRSID(ImageLevelInfo li, Connection con) throws IOException { Integer result = null; String schema = null; try { schema = getSchemaFromSpatialTable(li.getSpatialTableName()); PreparedStatement s = null; if (schema == null) { schema = "public"; } s = con.prepareStatement(SRSSelect); s.setString(1, schema); s.setString(2, li.getSpatialTableName()); s.setString(3, config.getGeomAttributeNameInSpatialTable()); ResultSet r = s.executeQuery(); if (r.next()) { result = (Integer) r.getObject(1); } r.close(); s.close(); } catch (SQLException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new IOException(e); } if (result == null) { String msg = MessageFormat.format( "No entry in geometry_columns for {0},{1},{2}", new Object[] { schema, li.getSpatialTableName(), config.getGeomAttributeNameInSpatialTable() }); LOGGER.log(Level.SEVERE, msg); throw new IOException(msg); } return result; }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccess#initialize() */ public void initialize() throws IOException { Connection con = null; try { con = dataSource.getConnection(); if (con.getAutoCommit()) { con.setAutoCommit(false); } initFromDB(config.getCoverageName(), con); calculateExtentsFromDB(config.getCoverageName(), con); calculateResolutionsFromDB(config.getCoverageName(), con); // con.commit(); con.close(); for (ImageLevelInfo levelInfo : levelInfos) { if (LOGGER.isLoggable(Level.INFO)) LOGGER.info(levelInfo.infoString()); } } catch (SQLException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); try { // con.rollback(); con.close(); } catch (SQLException e1) { } LOGGER.severe(e.getMessage()); throw new IOException(e); } if (levelInfos.isEmpty()) { String msg = "No level available for " + config.getCoverageName(); LOGGER.severe(msg); throw new IOException(msg); } // sort levelinfos SortedSet<ImageLevelInfo> sortColl = new TreeSet<ImageLevelInfo>(); sortColl.addAll(levelInfos); levelInfos = new ArrayList<ImageLevelInfo>(); levelInfos.addAll(sortColl); }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#getCRS(org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo, * java.sql.Connection) */ @Override protected CoordinateReferenceSystem getCRS(ImageLevelInfo li, Connection con) throws IOException { CoordinateReferenceSystem result = null; try { PreparedStatement s = con.prepareStatement(CRSSelect); s.setInt(1, li.getSrsId()); ResultSet r = s.executeQuery(); if (r.next()) { String definition = r.getString(1); result = CRS.parseWKT(definition); } r.close(); s.close(); } catch (Exception e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new IOException(e); } return result; }
Envelope getBounds(int level) throws IOException { ImageLevelInfo li = levelInfos.get(level); return li.getEnvelope(); }
/** * Step 3 of the bootstrapping process. * * <p>Calculating the the resolution for each image level (original + pyramids). This calculation * is only done if the resultion info in the master table is SQL NULL. After calculation the meta * table is updated with the result to avoid this operation in the future. * * @param coverageName The coverage name in the sql meta table * @param con JDBC Connection * @throws SQLException * @throws IOException */ void calculateResolutionsFromDB(String coverageName, Connection con) throws SQLException, IOException { PreparedStatement stmt = null; stmt = con.prepareStatement(config.getSqlUpdateResStatement()); List<ImageLevelInfo> toBeRemoved = new ArrayList<ImageLevelInfo>(); for (ImageLevelInfo li : levelInfos) { if (li.getCoverageName().equals(coverageName) == false) { continue; } if (li.calculateResolutionNeeded() == false) { continue; } Date start = new Date(); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("Calculate resolutions for " + li.toString()); double[] resolutions = getPixelResolution(li, con); if (resolutions == null) { if (LOGGER.isLoggable(Level.WARNING)) LOGGER.log(Level.WARNING, "No image found, removing " + li.toString()); toBeRemoved.add(li); continue; } li.setResX(resolutions[0]); li.setResY(resolutions[1]); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("ResX: " + li.getResX() + " ResY: " + li.getResY()); // li.setColorModel(loadedImage.getColorModel()); stmt.setDouble(1, li.getResX().doubleValue()); stmt.setDouble(2, li.getResY().doubleValue()); stmt.setString(3, li.getCoverageName()); stmt.setString(4, li.getTileTableName()); stmt.setString(5, li.getSpatialTableName()); stmt.execute(); long msecs = (new Date()).getTime() - start.getTime(); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info( "Calculate resolutions for " + li.toString() + " finished in " + msecs + " ms "); } levelInfos.removeAll(toBeRemoved); if (stmt != null) { stmt.close(); } }
/** * Step 2 of the bootstrapping process. * * <p>Calculating the the extent for each image level (original + pyramids). This calculation is * only done if the extent info in the master table is SQL NULL. After calculation the meta table * is updated with the result to avoid this operation in the future. * * @param coverageName The coverage name in the sql meta table * @param con JDBC connection * @throws SQLException * @throws IOException */ void calculateExtentsFromDB(String coverageName, Connection con) throws SQLException, IOException { PreparedStatement stmt = con.prepareStatement(config.getSqlUpdateMosaicStatement()); List<ImageLevelInfo> toBeRemoved = new ArrayList<ImageLevelInfo>(); for (ImageLevelInfo li : levelInfos) { if (li.getCoverageName().equals(coverageName) == false) { continue; } if (li.calculateExtentsNeeded() == false) { continue; } Date start = new Date(); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("Calculate extent for " + li.toString()); Envelope env = getExtent(li, con); if (env == null) { if (LOGGER.isLoggable(Level.WARNING)) LOGGER.log(Level.WARNING, "No extent, removing this level"); toBeRemoved.add(li); continue; } li.setExtentMaxX(new Double(env.getMaxX())); li.setExtentMaxY(new Double(env.getMaxY())); li.setExtentMinX(new Double(env.getMinX())); li.setExtentMinY(new Double(env.getMinY())); stmt.setDouble(1, li.getExtentMaxX().doubleValue()); stmt.setDouble(2, li.getExtentMaxY().doubleValue()); stmt.setDouble(3, li.getExtentMinX().doubleValue()); stmt.setDouble(4, li.getExtentMinY().doubleValue()); stmt.setString(5, li.getCoverageName()); stmt.setString(6, li.getTileTableName()); stmt.setString(7, li.getSpatialTableName()); stmt.execute(); long msecs = (new Date()).getTime() - start.getTime(); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("Calculate extent for " + li.toString() + " finished in " + msecs + " ms "); } levelInfos.removeAll(toBeRemoved); if (stmt != null) { stmt.close(); } }
/** * Step 1 of the bootstrapping process. Read meta table and build the ImageLevelInfo objects * * @param coverageName the coverage name stored in the sql meta table * @param con jdbc connection * @throws SQLException * @throws IOException */ protected void initFromDB(String coverageName, Connection con) throws SQLException, IOException { PreparedStatement s = null; ResultSet res = null; try { String stmt = config.getSqlSelectCoverageStatement(); // TODO, investigate, setString for oracle does not work stmt = stmt.replace("?", "'" + coverageName + "'"); s = con.prepareStatement(stmt); // s.setString(1,coverageName); res = s.executeQuery(); while (res.next()) { ImageLevelInfo imageLevelInfo = new ImageLevelInfo(); imageLevelInfo.setCoverageName(coverageName); imageLevelInfo.setSpatialTableName(res.getString(config.getSpatialTableNameAtribute())); imageLevelInfo.setTileTableName((res.getString(config.getTileTableNameAtribute()))); // check cardinalities if (config.getVerifyCardinality().booleanValue()) { imageLevelInfo.setCountFeature( new Integer(getRowCount(imageLevelInfo.getSpatialTableName(), con))); if (imageLevelInfo.getSpatialTableName().equals(imageLevelInfo.getTileTableName())) { imageLevelInfo.setCountTiles(imageLevelInfo.getCountFeature()); } else { imageLevelInfo.setCountTiles( new Integer(getRowCount(imageLevelInfo.getTileTableName(), con))); } if (imageLevelInfo.getCountFeature().intValue() == 0) { LOGGER.severe("Table " + imageLevelInfo.getSpatialTableName() + " has no entries"); } else if (imageLevelInfo.getCountTiles().intValue() == 0) { LOGGER.severe("Table " + imageLevelInfo.getTileTableName() + " has no entries"); } else if (imageLevelInfo.getCountFeature().intValue() != imageLevelInfo.getCountTiles().intValue()) { if (LOGGER.isLoggable(Level.WARNING)) LOGGER.log( Level.WARNING, "Consistency warning: number of features: " + imageLevelInfo.getCountFeature() + " number tiles: " + imageLevelInfo.getCountTiles()); } else { if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine( "Number of features: " + imageLevelInfo.getCountFeature() + " number tiles: " + imageLevelInfo.getCountTiles()); } } imageLevelInfo.setExtentMaxX(new Double(res.getDouble(config.getMaxXAttribute()))); if (res.wasNull()) { imageLevelInfo.setExtentMaxX(null); } imageLevelInfo.setExtentMaxY(new Double(res.getDouble(config.getMaxYAttribute()))); if (res.wasNull()) { imageLevelInfo.setExtentMaxY(null); } imageLevelInfo.setExtentMinX(new Double(res.getDouble(config.getMinXAttribute()))); if (res.wasNull()) { imageLevelInfo.setExtentMinX(null); } imageLevelInfo.setExtentMinY(new Double(res.getDouble(config.getMinYAttribute()))); if (res.wasNull()) { imageLevelInfo.setExtentMinY(null); } imageLevelInfo.setResX(new Double(res.getDouble(config.getResXAttribute()))); if (res.wasNull()) { imageLevelInfo.setResX(null); } imageLevelInfo.setResY(new Double(res.getDouble(config.getResYAttribute()))); if (res.wasNull()) { imageLevelInfo.setResY(null); } if (config.getVerifyCardinality().booleanValue()) { if ((imageLevelInfo.getCountFeature().intValue() > 0) && (imageLevelInfo.getCountTiles().intValue() > 0)) { levelInfos.add(imageLevelInfo); } } else { levelInfos.add(imageLevelInfo); } imageLevelInfo.setSrsId(getSRSID(imageLevelInfo, con)); imageLevelInfo.setCrs(getCRS(imageLevelInfo, con)); } } catch (SQLException e) { throw (e); } catch (IOException e1) { throw (e1); } finally { if (res != null) { res.close(); } if (s != null) { s.close(); } } }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccessBase#getExtentSelectStatment(org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo) */ @Override protected String getExtentSelectStatment(ImageLevelInfo li) { return MessageFormat.format(extentSelect, new Object[] {li.getSpatialTableName()}); }