performance x20
This commit is contained in:
+20
-20
@@ -3,6 +3,11 @@
|
|||||||
-- https://sites.google.com/site/polesofinaccessibility/
|
-- https://sites.google.com/site/polesofinaccessibility/
|
||||||
-- Requires: https://github.com/CartoDB/cartodb-postgresql
|
-- Requires: https://github.com/CartoDB/cartodb-postgresql
|
||||||
|
|
||||||
|
-- Based on:
|
||||||
|
-- https://github.com/mapbox/polylabel/blob/master/index.js
|
||||||
|
-- https://sites.google.com/site/polesofinaccessibility/
|
||||||
|
-- Requires: https://github.com/CartoDB/cartodb-postgresql
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION CDB_PIA(
|
CREATE OR REPLACE FUNCTION CDB_PIA(
|
||||||
IN polygon geometry,
|
IN polygon geometry,
|
||||||
IN tolerance numeric DEFAULT 1.0
|
IN tolerance numeric DEFAULT 1.0
|
||||||
@@ -11,12 +16,12 @@ RETURNS geometry AS $$
|
|||||||
DECLARE
|
DECLARE
|
||||||
env geometry[];
|
env geometry[];
|
||||||
cells geometry[];
|
cells geometry[];
|
||||||
|
cell geometry;
|
||||||
best_c geometry;
|
best_c geometry;
|
||||||
best_d numeric;
|
best_d numeric;
|
||||||
test_d numeric;
|
test_d numeric;
|
||||||
test_mx numeric;
|
test_mx numeric;
|
||||||
test_h numeric;
|
test_h numeric;
|
||||||
test_tol numeric;
|
|
||||||
test_cells geometry[];
|
test_cells geometry[];
|
||||||
width numeric;
|
width numeric;
|
||||||
height numeric;
|
height numeric;
|
||||||
@@ -31,19 +36,16 @@ BEGIN
|
|||||||
-- grid #0 cell size
|
-- grid #0 cell size
|
||||||
height := ST_YMax(polygon) - ST_YMin(polygon);
|
height := ST_YMax(polygon) - ST_YMin(polygon);
|
||||||
width := ST_XMax(polygon) - ST_XMin(polygon);
|
width := ST_XMax(polygon) - ST_XMin(polygon);
|
||||||
SELECT 0.5*LEAST(height, width) INTO h;
|
h := 0.5*LEAST(height, width);
|
||||||
|
|
||||||
-- grid #0
|
-- grid #0
|
||||||
with c1 as(
|
with c1 as(
|
||||||
SELECT CDB_RectangleGrid(polygon, h, h) as cell
|
SELECT CDB_RectangleGrid(polygon, h, h) as c
|
||||||
)
|
)
|
||||||
-- ,c2 as(
|
SELECT array_agg(c) INTO cells FROM c1;
|
||||||
-- SELECT cell FROM c1 WHERE ST_Intersects(cell, polygon)
|
|
||||||
-- )
|
|
||||||
SELECT array_agg(cell) INTO cells FROM c1;
|
|
||||||
|
|
||||||
-- 1st guess: centroid
|
-- 1st guess: centroid
|
||||||
SELECT _Signed_Dist(polygon, ST_Centroid(Polygon)) INTO best_d;
|
best_d := _Signed_Dist(polygon, ST_Centroid(Polygon));
|
||||||
|
|
||||||
-- looping the loop
|
-- looping the loop
|
||||||
n := array_length(cells,1);
|
n := array_length(cells,1);
|
||||||
@@ -52,41 +54,39 @@ BEGIN
|
|||||||
|
|
||||||
EXIT WHEN i > n;
|
EXIT WHEN i > n;
|
||||||
|
|
||||||
-- cell side size
|
cell := cells[i];
|
||||||
SELECT ST_XMax(cells[i]) - ST_XMin(cells[i]) INTO test_h;
|
i := i+1;
|
||||||
|
|
||||||
|
-- cell side size, it's square
|
||||||
|
test_h := ST_XMax(cell) - ST_XMin(cell) ;
|
||||||
|
|
||||||
-- check distance
|
-- check distance
|
||||||
SELECT _Signed_Dist(polygon, ST_Centroid(cells[i])) INTO test_d;
|
test_d := _Signed_Dist(polygon, ST_Centroid(cell));
|
||||||
IF test_d > best_d THEN
|
IF test_d > best_d THEN
|
||||||
best_d := test_d;
|
best_d := test_d;
|
||||||
best_c := cells[i];
|
best_c := cells[i];
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- longest distance within the cell
|
-- longest distance within the cell
|
||||||
SELECT test_d + (test_h * sqr) INTO test_mx;
|
test_mx := test_d + (test_h/2 * sqr);
|
||||||
|
|
||||||
-- if the cell has no chance to contains the desired point, continue
|
-- if the cell has no chance to contains the desired point, continue
|
||||||
SELECT test_mx - best_d INTO test_tol;
|
CONTINUE WHEN test_mx - best_d <= tolerance;
|
||||||
IF test_tol <= tolerance THEN
|
|
||||||
i := i+1;
|
|
||||||
CONTINUE;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- resample the cell
|
-- resample the cell
|
||||||
with c1 as(
|
with c1 as(
|
||||||
SELECT CDB_RectangleGrid(cells[i], test_h/2, test_h/2) as cell
|
SELECT CDB_RectangleGrid(cell, test_h/2, test_h/2) as c
|
||||||
)
|
)
|
||||||
-- , c2 as(
|
-- , c2 as(
|
||||||
-- SELECT cell FROM c1 WHERE ST_Intersects(cell, polygon)
|
-- SELECT cell FROM c1 WHERE ST_Intersects(cell, polygon)
|
||||||
-- )
|
-- )
|
||||||
SELECT array_agg(cell) INTO test_cells FROM c1;
|
SELECT array_agg(c) INTO test_cells FROM c1;
|
||||||
|
|
||||||
-- concat the new cells to the former array
|
-- concat the new cells to the former array
|
||||||
cells := cells || test_cells;
|
cells := cells || test_cells;
|
||||||
|
|
||||||
-- prepare next iteration
|
-- prepare next iteration
|
||||||
n := array_length(cells,1);
|
n := array_length(cells,1);
|
||||||
i := i+1;
|
|
||||||
|
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
st_astext
|
st_astext
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
POINT(-409081.241940808 4930027.50443989)
|
POINT(-409081.865887381 4930017.52075948)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user