如何在 PostGIS 数据库中存储值网格,以便 GeoServer 可以对其进行轮廓分析?



我计划将 GeoServer 与 PostGIS 数据库结合使用,以通过 Web 制图服务提供等值线。

我有一个简单的经度网格,我想将其存储在数据库中并具有轮廓。虽然 GeoServer 用户手册暗示在此示例中是可能的......

https://docs.geoserver.org/stable/en/user/styling/sld/extensions/rendering-transform.html#contour-extraction

。它没有讨论数据应该采用什么格式。请谁能建议一个合适的 PostGIS 数据库架构,我可以使用 GeoServer 将理解并能够勾勒轮廓?最好是与上面链接中的地理服务器示例一起使用的。

感谢您的帮助。

由于您的数据已经在Java程序中,因此我将深入研究GeoTools,这是GeoServer用于执行实际工作的底层库。

查看ContourProcess,您实际需要的是GridCoverage2D,这是对二维渲染图像支持的网格数据值的基本访问。影像中的每个波段都表示为一个样本维度。

因此,您需要获取数据数组并执行以下操作:

WritableRaster raster2 = RasterFactory.createBandedRaster(java.awt.image.DataBuffer.TYPE_INT, w,
h, 1, null);
for (int i = 0; i < w; i++) {//width...
for (int j = 0; j < h; j++) {
raster2.setSample(i, j, 0, myData[i*w+j]);
}
}
GridCoverageFactory gcf = new GridCoverageFactory();
// Here I'm using OSGB as I live in the UK you would be using something else
CoordinateReferenceSystem crs = CRS.decode("EPSG:27700");
// Position of Lower Left Corner of grid
int llx = 500000;
int lly = 105000;
// Pixel size in projection units
int resolution = 10;
ReferencedEnvelope referencedEnvelope = new ReferencedEnvelope(llx, llx + (w * resolution), lly, lly + (h * resolution),
crs);
GridCoverage2D gc = gcf.create("name", raster2, referencedEnvelope);

然后,您可以将其写出GeoTiff,也可以将上述所有内容包装到返回轮廓的新进程中。

所以我玩了一会儿,可以确认@IanTurton的代码就像一个魅力。这是我基于他的最终代码,主要区别在于我使用的是经纬度/经度坐标参考系统,并且我包含了一些代码将栅格写出为 GeoTIFF...

import java.awt.image.WritableRaster;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.io.File;
import java.io.IOException;
import javax.media.jai.RasterFactory;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.geotiff.GeoTiffWriter;
import org.opengis.parameter.ParameterValue;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
public class GridToGeoTiff {
public static void main(String[] args) throws NoSuchAuthorityCodeException, FactoryException, IllegalArgumentException, IndexOutOfBoundsException, IOException {
// Define the data grid
double[][] myGrid = {
{ 0.0, 0.2, 0.6, 0.3 },
{ 0.1, 1.1, 0.8, 0.7 },
{ 1.1, 2.6, 3.4, 0.3 },
{ 0.3, 0.9, 0.6, 0.1 }
};
int w = myGrid.length;
int h = myGrid[0].length;
// Position of Lower Left Corner of grid
double southBound = 51.5074; // degrees latitude
double westBound = 0.1278; // degrees latitude
double resolution = 0.001; // degrees lat/long
// Convert to a Raster
WritableRaster raster2 = RasterFactory.createBandedRaster(java.awt.image.DataBuffer.TYPE_INT, w, h, h, null);
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
raster2.setSample(i, j, 0, myGrid[j][i]);
}
}
// Create a GeoTools 2D grid referenced in lat/long 
GridCoverageFactory gcf = new GridCoverageFactory();
CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
ReferencedEnvelope referencedEnvelope = new ReferencedEnvelope(
westBound, westBound + (w * resolution), southBound, southBound + (h * resolution), crs
);
GridCoverage2D gc = gcf.create("my-grid", raster2, referencedEnvelope);
// Write out to a GeoTIFF file
final File geotiff = new File("my-grid.tif");
final ImageOutputStream imageOutStream = ImageIO.createImageOutputStream(geotiff);
GeoTiffWriter writer = new GeoTiffWriter(imageOutStream);
final ParameterValue<Boolean> tfw = GeoTiffFormat.WRITE_TFW.createValue();
tfw.setValue(true);
writer.write(gc, null);
writer.dispose();
}
}

我正在使用以下 Maven 依赖项...

  • org.geotools22.2: gt-main, gt-coverage, gt-referencing, gt-geometry, gt-geotiff
  • org.opengis2.2.0: geoapi
  • org.locationtech.jts1.16.1: jts-core
  • javax.media.jai1.1.3: com.springsource.javax.media.jai.core

。来自 Boundless 和 OSGeo 存储库。

使用此代码创建 GeoTIFF 文件后,我可以使用它在 GeoServer 中设置存储,然后发布它。我在GeoServer的轮廓示例中调整了SLD(实际上只是更改了名称和轮廓阈值(以创建样式,然后将其应用于已发布的GeoTIFF数据,瞧,地图上的等值线!

但。。。我的数据不是静态的,我将生成许多不同的网格,因此这种基于文件的方法会有点笨拙。因此,我将研究GeoServer的ImageMosaic插件,作为直接从数据库中获取轮廓的一种方式。但是,这似乎不是一个流行的选择,并且可能还没有准备好生产(根据这篇文章(,所以我最终可能会自己勾勒出数据的轮廓并将其存储为矢量。如果有人对此有进一步的想法,我很想听听。

感谢大家的帮助!

最新更新