Created
August 25, 2021 17:59
-
-
Save bitner/1d3cf94a2865f1792789f1b472686570 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE OR REPLACE FUNCTION xyzsearch_asmvtrows( | |
IN _x int, | |
IN _y int, | |
IN _z int, | |
IN queryhash text, | |
IN fields jsonb DEFAULT NULL, | |
IN _scanlimit int DEFAULT 10000, | |
IN _limit int DEFAULT 100, | |
IN _timelimit interval DEFAULT '5 seconds'::interval, | |
IN exitwhenfull boolean DEFAULT TRUE, -- Return as soon as the passed in geometry is full covered | |
IN skipcovered boolean DEFAULT TRUE, -- Skip any items that would show up completely under the previous items | |
OUT mvtgeom geometry, | |
OUT id text | |
) RETURNS setof RECORD AS $$ | |
DECLARE | |
search searches%ROWTYPE; | |
curs refcursor; | |
_where text; | |
query text; | |
iter_record items%ROWTYPE; | |
out_records jsonb[] := '{}'::jsonb[]; | |
exit_flag boolean := FALSE; | |
counter int := 1; | |
scancounter int := 1; | |
remaining_limit int := _scanlimit; | |
tilearea float; | |
geom geometry; | |
unionedgeom geometry; | |
clippedgeom geometry; | |
unionedgeom_area float := 0; | |
prev_area float := 0; | |
excludes text[]; | |
includes text[]; | |
BEGIN | |
-- If skipcovered is true then you will always want to exit when the passed in geometry is full | |
IF skipcovered THEN | |
exitwhenfull := TRUE; | |
END IF; | |
geom := st_transform(tileenvelope(_z, _x, _y), 4326); | |
SELECT * INTO search FROM searches WHERE hash=queryhash; | |
IF NOT FOUND THEN | |
RAISE EXCEPTION 'Search with Query Hash % Not Found', queryhash; | |
END IF; | |
tilearea := st_area(geom); | |
_where := format('%s AND st_intersects(geometry, %L::geometry)', search._where, geom); | |
FOR query IN SELECT * FROM partition_queries(_where, search.orderby) LOOP | |
query := format('%s LIMIT %L', query, remaining_limit); | |
RAISE NOTICE '%', query; | |
curs = create_cursor(query); | |
LOOP | |
FETCH curs INTO iter_record; | |
EXIT WHEN NOT FOUND; | |
IF exitwhenfull OR skipcovered THEN -- If we are not using exitwhenfull or skipcovered, we do not need to do expensive geometry operations | |
clippedgeom := st_intersection(geom, iter_record.geometry); | |
IF unionedgeom IS NULL THEN | |
unionedgeom := clippedgeom; | |
ELSE | |
unionedgeom := st_union(unionedgeom, clippedgeom); | |
END IF; | |
unionedgeom_area := st_area(unionedgeom); | |
IF skipcovered AND prev_area = unionedgeom_area THEN | |
scancounter := scancounter + 1; | |
CONTINUE; | |
END IF; | |
prev_area := unionedgeom_area; | |
RAISE NOTICE '% % % %', unionedgeom_area/tilearea, counter, scancounter, ftime(); | |
END IF; | |
mvtgeom := ST_ASMVTGeom( | |
ST_Transform(iter_record.geometry, 3857), | |
box2d(st_transform(geom, 3857)), | |
4096, | |
0, | |
TRUE | |
); | |
id := iter_record.id; | |
RETURN NEXT; | |
IF counter >= _limit | |
OR scancounter > _scanlimit | |
OR ftime() > _timelimit | |
OR (exitwhenfull AND unionedgeom_area >= tilearea) | |
THEN | |
exit_flag := TRUE; | |
EXIT; | |
END IF; | |
counter := counter + 1; | |
scancounter := scancounter + 1; | |
END LOOP; | |
EXIT WHEN exit_flag; | |
remaining_limit := _scanlimit - scancounter; | |
END LOOP; | |
RETURN; | |
END; | |
$$ LANGUAGE PLPGSQL; | |
CREATE OR REPLACE FUNCTION xyzsearch_asmvt( | |
IN _x int, | |
IN _y int, | |
IN _z int, | |
IN queryhash text, | |
IN fields jsonb DEFAULT NULL, | |
IN _scanlimit int DEFAULT 10000, | |
IN _limit int DEFAULT 100, | |
IN _timelimit interval DEFAULT '5 seconds'::interval, | |
IN exitwhenfull boolean DEFAULT TRUE, | |
IN skipcovered boolean DEFAULT TRUE | |
) RETURNS bytea AS $$ | |
SELECT ST_ASMVT(m.*) FROM xyzsearch_asmvtrows( | |
_x, | |
_y, | |
_z, | |
queryhash, | |
fields, | |
_scanlimit, | |
_limit, | |
_timelimit, | |
exitwhenfull, | |
skipcovered | |
) m; | |
$$ LANGUAGE SQL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment