海量數據展示(二)-性能優化

背景

    之前做的海量數據數據展示,在預處理速度和在線渲染上還有有所欠缺,本文中進行一些優化工作,使得九分鐘處理完一千多萬面數據的3-12級矢量切片,在線瀏覽數據請求時間控制在10s左右。

準備

    軟件環境:PostGIS(3.0.0rc2 r17909)和 PostgreSQL( 12.0, compiled by Visual C++ build 1914, 64-bit),數據是微軟開源的部分房屋數據public.california20191107(10988317條)。

預處理

    預處理就是將3級到12級的矢量切片事先切好。首先獲取數據12級的最大最小xyz,通過這個範圍生成網格,然後和數據相交得到一一對應的網格表public.ca_xyz 。

<code>--經度轉切片x

CREATE OR REPLACE FUNCTION lon2tile(lon DOUBLE PRECISION, zoom INTEGER)

RETURNS INTEGER AS

$BODY$

SELECT FLOOR( (lon + 180) / 360 * (1 << zoom) )::INTEGER;

$BODY$

LANGUAGE SQL IMMUTABLE;

--緯度轉切片y

CREATE OR REPLACE FUNCTION lat2tile(lat double precision, zoom integer)

RETURNS integer AS

$BODY$

SELECT floor( (1.0 - ln(tan(radians(lat)) + 1.0 / cos(radians(lat))) / pi()) / 2.0 * (1 << zoom) )::integer;

$BODY$

LANGUAGE sql IMMUTABLE;

--xyz轉幾何

create or replace function TileBBox (z int, x int, y int, srid int = 3857)


returns geometry

language plpgsql immutable as

$func$

declare

max numeric := 20037508.34;

res numeric := (max*2)/(2^z);

bbox geometry;

begin

bbox := ST_MakeEnvelope(

-max + (x * res),

max - (y * res),

-max + (x * res) + res,

max - (y * res) - res,

3857

);

if srid = 3857 then

return bbox;

else

return ST_Transform(bbox, srid);

end if;

end;

$func$;

--數據最大最小經緯度計算最大最小xyz

select lat2tile(ST_Y((pt).geom),12) y, lon2tile(ST_X((pt).geom),12) x FROM (SELECT ST_DumpPoints(ST_Extent(geom)) AS pt from public.california20191107) as foo where (pt).path[2] in (1,3)

--網格表

CREATE TABLE public.ca_xyz ( x integer,y integer,z integer,id integer NOT NULL ) WITH (OIDS = FALSE) TABLESPACE pg_default;

--示例

insert into public.ca_xyz (id,z,x,y) select 1,3,1,3 from public.california20191107 where TileBBox(3,1,3,4326)&&geom limit 1
/<code>
海量數據展示(二)-性能優化

海量數據展示(二)-性能優化

    接下來就比較簡單了,將quadkey生成3-11級xyz,把所有的xyz用來生成矢量切片。

<code>--示例

SELECT ST_AsMVT(vt,'polygon',4096,'geo') tile FROM (SELECT ST_AsMVTGeom(geom,Box2D(TileBBox(3,1,3,4326)),4096,0,true) AS geo FROM public.california20191107 where TileBBox(3,1,3,4326)&&geom) AS vt
/<code>

後臺服務

    預處理矢量切片生成完以後,使用golang把矢量切片全部加載進程序中,並且建立鍵值對,能夠快速的判斷請求的xyz在3-12級是否有數據存在數據時能快速獲取。當數據請求大於12級時候,我們使用數據庫查詢方式獲取矢量切片。對於大於12級沒有緩存的數據會判斷是否是12級xyz的子級,如果是就會到數據庫查詢並緩存到程序中,如果不是就返回url無效減少數據庫查詢時間。


分享到:


相關文章: