Postgresql 在PostGIS中创建空平铺光栅表

Postgresql 在PostGIS中创建空平铺光栅表,postgresql,postgis,raster,tile,Postgresql,Postgis,Raster,Tile,我是postgres/postgis新手,正在尝试找出如何使用postgis制作空平铺光栅 我想生成一个包含5000 X 2000个单元格的空光栅,稍后我想查询它以在位置X/y处查找特定单元格或在位置X/y处添加单元格值。我将来基本上会将单个单元格值添加到空光栅中(例如,报告随时间推移在单元格中看到的动物) 我发现,通过首先创建光栅表,可以实现这一点: CREATE TABLE myRasterTable(rid serial primary key, rast raster); 然后添加一个

我是postgres/postgis新手,正在尝试找出如何使用postgis制作空平铺光栅

我想生成一个包含5000 X 2000个单元格的空光栅,稍后我想查询它以在位置X/y处查找特定单元格或在位置X/y处添加单元格值。我将来基本上会将单个单元格值添加到空光栅中(例如,报告随时间推移在单元格中看到的动物)

我发现,通过首先创建光栅表,可以实现这一点:

CREATE TABLE myRasterTable(rid serial primary key, rast raster);
然后添加一个空光栅:

INSERT INTO myRasterTable(rid,rast)
VALUES(1, ST_MakeEmptyRaster( 5000, 2000, 2485869.5728, 1299941.7864, 100, 100, 0, 0, 2056) );
(参考资料:)

我还为其中一个光栅单元添加了一个标注栏和一个值:

UPDATE myRasterTable SET rast = ST_AddBand(rast, 1, '32BF'::text, 0);
UPDATE myRasterTable SET rast = ST_SetValue(rast, 1,ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056),987.654321)
(参考资料:)

现在,我可以查询已设置的光栅单元的值:

// Location with value
SELECT rid, ST_Value(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056),false) val FROM myRasterTable
// Return = 987.654296875 in 0.5224609375 Seconds

// Location without value:
SELECT rid, ST_Value(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.0,48.5),4326),2056),false) val FROM myRasterTable
// Return =  0 in 0.51311993598938 Seconds
我发现很多帖子都在说,对于较大的光栅,查询性能至关重要,光栅的平铺范围为每个平铺100X100个单元格(参考文献:和)

现在我不知道:

  • 如何使用PostGIS中的大型光栅创建平铺,或者如何从PostGIS开始创建平铺光栅?换句话说:我需要使用什么查询来创建覆盖5000X2000光栅的光栅图幅集合,其中图幅的范围为100X100个单元格,包含多个条带
  • 创建平铺后,我需要创建单独的空间索引还是自动创建
  • 最后:在光栅平铺后,如何查询特定位置的单元格值

  • 任何帮助都将不胜感激

    经过反复试验,我似乎找到了解决办法

    为了在PostGIS中创建一个新表,其中包含总计5000 X 2000个单元格的空分幅,我使用了以下查询:

    CREATE TABLE myRasterTable (rid integer, rast raster);
    INSERT INTO myRasterTable(rast) VALUES(ST_Tile(ST_MakeEmptyRaster( 5000, 2000, 2485869.5728, 1299941.7864, 100, 100, 0, 0, 2056), 10,10, TRUE, NULL));
    
    这将使用ST_MakeEmptyMaster生成一个范围为5000 X 2000的临时光栅。然后,它使用ST_Tile将临时光栅平铺为10X10单元格平铺,并将这些平铺添加到表中

    然后我可以添加我的乐队:

    UPDATE myRasterTable SET rast = ST_AddBand(rast, 1, '32BUI'::text, 0, NULL);
    
    最后,我可以通过以下方式添加和检索值:

    // Add cell value
    UPDATE myRasterTable SET rast = ST_SetValue(rast, 1,ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056),987654321) WHERE ST_Intersects(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056));
    
    // Get cell value
    SELECT rid, ST_Value(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056), false) FROM myRasterTable WHERE ST_Intersects(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056));
    // Return = 987654321 in 0.22717499732971 Seconds
    
    如您所见,这已经将查询时间减少到了原来时间的约2/5

    如果我另外添加了一个索引:

    CREATE INDEX myRasterTable_rast_gist_idx ON myRasterTable USING GIST (ST_ConvexHull(rast));
    
    然后再次执行查询,我得到:

    // Get cell value
    SELECT rid, ST_Value(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056), false) FROM myRasterTable WHERE ST_Intersects(rast, ST_Transform(ST_SetSRID(ST_MakePoint(7.5,48.5),4326),2056));
    // Return = 987654321 in 0.084153890609741 Seconds
    
    如您所见,查询时间再次被削减了一半多一点,导致查询时间低于原始查询的1/5。 我还尝试了不同的瓷砖尺寸,发现10 X 10的瓷砖尺寸产生了最好的性能,但只比100 X 100的瓷砖尺寸稍微好一点

    如果有人有进一步的优化,请随意添加

    编辑(2016年7月8日)

    我写了一篇关于这个的小博文。如果感兴趣,您可以在此处查看: