Skip to content

Instantly share code, notes, and snippets.

@matthew-n
Forked from thiagomata/postgresql_grid.sql
Last active February 2, 2017 14:28
Show Gist options
  • Save matthew-n/5e5537b2d5f8066f46bc62c3dfcc348c to your computer and use it in GitHub Desktop.
Save matthew-n/5e5537b2d5f8066f46bc62c3dfcc348c to your computer and use it in GitHub Desktop.
reduce vars
/*
-- EXAMPLE --
SELECT
*
FROM grid(array(SELECT
(
lat,
lng,
count(*)
)::Pin
FROM MYSCHEMA.MYTABLE group by lat, lng ),
10, -- width
10 -- height
)
*/
CREATE TYPE pin AS (
lat float,
lng float,
count bigint
);
CREATE OR REPLACE FUNCTION GRID( inPins pin[],
width integer,
height integer )
RETURNS table
(
lat float,
lng float,
count bigint
) AS
$$
DECLARE
minLat float;
minLng float;
stepLat float;
stepLng float;
returnPins pin[];
BEGIN
/**
* calcuate bbox
*/
SELECT
MIN( t.lat ),
(MAX( t.lat )-MIN( t.lat )) / height,
MIN( t.lng ),
(MAX( t.lng ) - MIN( t.lng ))/ width
INTO
minLat, stepLat,
minLng, stepLng
FROM
unnest( inPins ) t;
/**
* CREATE INITAL DATA TO KM_CLUSTER
*/
RETURN QUERY
SELECT
SUM(PIN.lat*PIN.count)/SUM(PIN.count),
SUM(PIN.lng*PIN.count)/SUM(PIN.count),
SUM(PIN.count)
FROM
(
SELECT
minLat + stepLat * ( currentHeight ) AS fromLat,
minLat + stepLat * ( currentHeight + 1 ) AS toLat,
minLng + stepLng * ( currentWidth ) AS fromLng,
minLng + stepLng * ( currentWidth + 1 ) AS toLng
FROM
generate_series(0, width ) currentWidth,
generate_series(0, height) currentHeight
) as bounds
INNER JOIN unnest( inPins ) AS PIN
ON
PIN.lng BETWEEN bounds.fromLng AND bounds.toLng AND
PIN.lat BETWEEN bounds.fromLat AND bounds.toLat
GROUP BY fromLat, toLat, fromLng, toLng;
end;
$$ language plpgsql;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment