如何在 PostGIS 数据库中存储值网格,以便 GeoServer 可以绘制轮廓?
How to store a grid of values in a PostGIS database such that it can be contoured by GeoServer?
我计划将 GeoServer 与 PostGIS 数据库结合使用,以通过 Web 地图服务提供等高线。
我有一个简单的经纬度值网格,我想将其存储在数据库中并绘制轮廓。虽然 GeoServer 用户手册暗示在此示例中是可能的...
...它没有讨论数据应该采用什么格式。请有人建议我可以使用的合适的 PostGIS 数据库模式,GeoServer 可以理解并能够绘制轮廓?最好是可以与上面 link 中的 GeoServer 示例一起使用的一个。
感谢您的帮助。
由于您的数据已经在 Java 程序中,我将深入研究 GeoTools which is the underlying library that GeoServer 用于完成实际工作。
查看 ContourProcess what you actually need is a 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 或将以上所有内容包装到 a new Process 中 returns 等高线。
所以我玩了一把,可以确认@IanTurton 的代码很有魅力。这是我的最终代码,基于他的代码,主要区别在于我使用的是 lat/long 坐标参考系统,并且我包含了一些代码以将栅格写为 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.geotools 22.2: gt-main, gt-coverage, gt-referencing, gt-geometry, gt-geotiff
- org.opengis 2.2.0: geoapi
- org.locationtech.jts 1.16.1: jts-核心
- javax.media.jai 1.1.3: com.springsource.javax.media.jai.core
...来自 Boundless 和 OSGeo 存储库。
使用此代码创建 GeoTIFF 文件后,我可以使用它在 GeoServer 中设置商店,然后发布它。我在 GeoServer 的 contouring example 中调整了 SLD(实际上只是更改了名称和等高线阈值)来创建一种样式,然后我将其应用于已发布的 GeoTIFF 数据,等高线出现在地图上!
但是...我的数据不是静态的,我将生成许多不同的网格,因此这种基于文件的方法会有点笨拙。因此,我将研究 GeoServer 的 ImageMosaic plugin as a way of getting the contours straight from the database. However, it seems that this is not a popular option, and might not be production ready (according to this post),这样我最终可能会自己绘制数据轮廓并将其存储为矢量。如果有人对此有进一步的想法,我很想听听他们的意见。
感谢大家的帮助!
我计划将 GeoServer 与 PostGIS 数据库结合使用,以通过 Web 地图服务提供等高线。
我有一个简单的经纬度值网格,我想将其存储在数据库中并绘制轮廓。虽然 GeoServer 用户手册暗示在此示例中是可能的...
...它没有讨论数据应该采用什么格式。请有人建议我可以使用的合适的 PostGIS 数据库模式,GeoServer 可以理解并能够绘制轮廓?最好是可以与上面 link 中的 GeoServer 示例一起使用的一个。
感谢您的帮助。
由于您的数据已经在 Java 程序中,我将深入研究 GeoTools which is the underlying library that GeoServer 用于完成实际工作。
查看 ContourProcess what you actually need is a 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 或将以上所有内容包装到 a new Process 中 returns 等高线。
所以我玩了一把,可以确认@IanTurton 的代码很有魅力。这是我的最终代码,基于他的代码,主要区别在于我使用的是 lat/long 坐标参考系统,并且我包含了一些代码以将栅格写为 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.geotools 22.2: gt-main, gt-coverage, gt-referencing, gt-geometry, gt-geotiff
- org.opengis 2.2.0: geoapi
- org.locationtech.jts 1.16.1: jts-核心
- javax.media.jai 1.1.3: com.springsource.javax.media.jai.core
...来自 Boundless 和 OSGeo 存储库。
使用此代码创建 GeoTIFF 文件后,我可以使用它在 GeoServer 中设置商店,然后发布它。我在 GeoServer 的 contouring example 中调整了 SLD(实际上只是更改了名称和等高线阈值)来创建一种样式,然后我将其应用于已发布的 GeoTIFF 数据,等高线出现在地图上!
但是...我的数据不是静态的,我将生成许多不同的网格,因此这种基于文件的方法会有点笨拙。因此,我将研究 GeoServer 的 ImageMosaic plugin as a way of getting the contours straight from the database. However, it seems that this is not a popular option, and might not be production ready (according to this post),这样我最终可能会自己绘制数据轮廓并将其存储为矢量。如果有人对此有进一步的想法,我很想听听他们的意见。
感谢大家的帮助!