Compare commits
13 Commits
develop
...
better_dot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e479f84cf9 | ||
|
|
f9c1b57dfd | ||
|
|
4c175c9565 | ||
|
|
de6f228e72 | ||
|
|
87f9b2c787 | ||
|
|
fda5d93cf4 | ||
|
|
0748212610 | ||
|
|
27b18f5e1c | ||
|
|
3649f958c8 | ||
|
|
faaf5e419a | ||
|
|
1f3b74e54f | ||
|
|
2bc6b0782a | ||
|
|
b8fe05b388 |
@@ -36,7 +36,10 @@ before_install:
|
|||||||
- sudo apt-get -y remove --purge postgresql-9.3
|
- sudo apt-get -y remove --purge postgresql-9.3
|
||||||
- sudo apt-get -y remove --purge postgresql-9.4
|
- sudo apt-get -y remove --purge postgresql-9.4
|
||||||
- sudo apt-get -y remove --purge postgresql-9.5
|
- sudo apt-get -y remove --purge postgresql-9.5
|
||||||
- sudo apt-get -y remove --purge postgis
|
- sudo rm -rf /var/lib/postgresql/
|
||||||
|
- sudo rm -rf /var/log/postgresql/
|
||||||
|
- sudo rm -rf /etc/postgresql/
|
||||||
|
- sudo apt-get -y remove --purge postgis-2.2
|
||||||
- sudo apt-get -y autoremove
|
- sudo apt-get -y autoremove
|
||||||
|
|
||||||
- sudo apt-get -y install postgresql-9.5=9.5.2-3cdb2
|
- sudo apt-get -y install postgresql-9.5=9.5.2-3cdb2
|
||||||
|
|||||||
@@ -10,45 +10,192 @@
|
|||||||
-- misses per point the funciton accepts before giving up.
|
-- misses per point the funciton accepts before giving up.
|
||||||
--
|
--
|
||||||
-- Returns: Multipoint with the requested points
|
-- Returns: Multipoint with the requested points
|
||||||
CREATE OR REPLACE FUNCTION cdb_dot_density(geom geometry , no_points Integer, max_iter_per_point Integer DEFAULT 1000)
|
|
||||||
RETURNS GEOMETRY AS $$
|
|
||||||
DECLARE
|
|
||||||
extent GEOMETRY;
|
|
||||||
test_point Geometry;
|
|
||||||
width NUMERIC;
|
|
||||||
height NUMERIC;
|
|
||||||
x0 NUMERIC;
|
|
||||||
y0 NUMERIC;
|
|
||||||
xp NUMERIC;
|
|
||||||
yp NUMERIC;
|
|
||||||
no_left INTEGER;
|
|
||||||
remaining_iterations INTEGER;
|
|
||||||
points GEOMETRY[];
|
|
||||||
bbox_line GEOMETRY;
|
|
||||||
intersection_line GEOMETRY;
|
|
||||||
BEGIN
|
|
||||||
extent := ST_Envelope(geom);
|
|
||||||
width := ST_XMax(extent) - ST_XMIN(extent);
|
|
||||||
height := ST_YMax(extent) - ST_YMIN(extent);
|
|
||||||
x0 := ST_XMin(extent);
|
|
||||||
y0 := ST_YMin(extent);
|
|
||||||
no_left := no_points;
|
|
||||||
|
|
||||||
LOOP
|
CREATE OR REPLACE FUNCTION CDB_DotDensity(g geometry(Polygon, 4326), no_points integer, max_iter integer DEFAULT 1000)
|
||||||
if(no_left=0) THEN
|
RETURNS SETOF geometry(Point, 4326)
|
||||||
EXIT;
|
AS $$
|
||||||
END IF;
|
DECLARE
|
||||||
yp = y0 + height*random();
|
extent GEOMETRY;
|
||||||
bbox_line = ST_MakeLine(
|
eq_area_geom GEOMETRY;
|
||||||
ST_SetSRID(ST_MakePoint(yp, x0),4326),
|
test_point Geometry;
|
||||||
ST_SetSRID(ST_MakePoint(yp, x0+width),4326)
|
iter NUMERIC;
|
||||||
);
|
width NUMERIC;
|
||||||
intersection_line = ST_Intersection(bbox_line,geom);
|
height NUMERIC;
|
||||||
test_point = ST_LineInterpolatePoint(st_makeline(st_linemerge(intersection_line)),random());
|
x0 NUMERIC;
|
||||||
points := points || test_point;
|
y0 NUMERIC;
|
||||||
no_left = no_left - 1 ;
|
no_left INTEGER;
|
||||||
END LOOP;
|
sample_points GEOMETRY[];
|
||||||
RETURN ST_Collect(points);
|
points GEOMETRY[];
|
||||||
|
BEGIN
|
||||||
|
eq_area_geom := ST_TRANSFORM(g, 2163);
|
||||||
|
extent := ST_Envelope(eq_area_geom);
|
||||||
|
iter := 0;
|
||||||
|
width := ST_XMax(extent) - ST_XMIN(extent);
|
||||||
|
height := ST_YMax(extent) - ST_YMIN(extent);
|
||||||
|
x0 := ST_XMin(extent);
|
||||||
|
y0 := ST_YMin(extent);
|
||||||
|
no_left := no_points;
|
||||||
|
|
||||||
|
LOOP
|
||||||
|
IF(no_left <= 0 or iter >= max_iter) THEN
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
with random_points as(
|
||||||
|
SELECT ST_SetSRID(ST_MAKEPOINT( x0 + width*random(), y0 + height*random()), 2163) as p
|
||||||
|
FROM generate_series(1,no_left)
|
||||||
|
)
|
||||||
|
SELECT array_agg(p) from random_points
|
||||||
|
WHERE ST_WITHIN(p, eq_area_geom)
|
||||||
|
into sample_points;
|
||||||
|
|
||||||
|
RETURN QUERY select ST_TRANSFORM(a, 4326) from unnest(sample_points) as a;
|
||||||
|
|
||||||
|
IF sample_points IS NOT null THEN
|
||||||
|
no_left := no_left - array_length(sample_points, 1);
|
||||||
|
END IF;
|
||||||
|
iter = iter + 1;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
RETURN;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- DEPRECATED
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dot_density(geom geometry, no_points Integer, max_iter_per_point Integer DEFAULT 1000)
|
||||||
|
RETURNS GEOMETRY
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
final_points GEOMETRY;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
with new_points as(
|
||||||
|
SELECT * FROM CDB_DotDensity(geom, no_points, max_iter_per_point) as a
|
||||||
|
)
|
||||||
|
SELECT ST_Collect(a) FROM new_points
|
||||||
|
into final_points;
|
||||||
|
RETURN final_points;
|
||||||
|
|
||||||
END;
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Creates N points randomly distributed in the specified secondary polygons
|
||||||
|
--
|
||||||
|
-- @param g - array of the geometries to be turned in to points
|
||||||
|
--
|
||||||
|
-- @param no_points - the number of points to generate
|
||||||
|
--
|
||||||
|
-- @params max_iter_per_point - the function generates points in the polygon's bounding box
|
||||||
|
-- and discards points which don't lie in the polygon. max_iter_per_point specifies how many
|
||||||
|
-- misses per point the funciton accepts before giving up.
|
||||||
|
--
|
||||||
|
-- Returns: Multipoint with the requested points
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Generate a random response based on the weights given
|
||||||
|
--
|
||||||
|
-- @param array_ids an array of ids representing the category to return
|
||||||
|
--
|
||||||
|
-- @param weights an array of weights for each category
|
||||||
|
--
|
||||||
|
-- Returns : The randomly selected ID.
|
||||||
|
|
||||||
|
CREATE OR REPLACE function _cdb_SelectRandomWeights(array_ids numeric[], weights numeric[]) returns NUMERIC
|
||||||
|
as $$
|
||||||
|
DECLARE
|
||||||
|
result NUMERIC;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
WITH idw as (
|
||||||
|
select unnest(array_ids) as id, unnest(weights) as percent
|
||||||
|
),
|
||||||
|
CTE AS (
|
||||||
|
SELECT random() * (SELECT SUM(percent) FROM idw) R
|
||||||
|
)
|
||||||
|
SELECT *
|
||||||
|
FROM (
|
||||||
|
SELECT id, SUM(percent) OVER (ORDER BY id) S, R
|
||||||
|
FROM idw as percent CROSS JOIN CTE
|
||||||
|
) Q
|
||||||
|
WHERE S >= R
|
||||||
|
ORDER BY id
|
||||||
|
LIMIT 1
|
||||||
|
into result;
|
||||||
|
return result;
|
||||||
|
END
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Weighted Dot Density
|
||||||
|
--
|
||||||
|
-- @param no_points the number of points to generate
|
||||||
|
--
|
||||||
|
-- @param geoms the target geometries to place the points in
|
||||||
|
--
|
||||||
|
-- @param weights the weight for each of the target polygons
|
||||||
|
--
|
||||||
|
-- RETURNS set of points
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION _cdb_WeightedDD(no_points numeric, geoms geometry[], weights numeric[])
|
||||||
|
RETURNS SETOF geometry
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
i NUMERIC;
|
||||||
|
ids NUMERIC[];
|
||||||
|
perGeom NUMERIC[];
|
||||||
|
selected_poly NUMERIC;
|
||||||
|
BEGIN
|
||||||
|
with idseries as (
|
||||||
|
select generate_series(1,array_upper(geoms,1)) as id
|
||||||
|
)
|
||||||
|
select array_agg(id) from idseries into ids;
|
||||||
|
|
||||||
|
FOR i in 1..no_points
|
||||||
|
LOOP
|
||||||
|
select cdb_crankshaft._cdb_SelectRandomWeights(ids, weights) INTO selected_poly;
|
||||||
|
perGeom[selected_poly] = coalesce(perGeom[selected_poly] + 1, 0 );
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
raise notice 'pergeom %', perGeom;
|
||||||
|
|
||||||
|
FOR i in 1..array_length(ids,1)
|
||||||
|
LOOP
|
||||||
|
return QUERY
|
||||||
|
select cdb_crankshaft.CDB_DotDensity(geoms[i], coalesce(perGeom[i],0)::INTEGER);
|
||||||
|
END LOOP;
|
||||||
|
END
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql VOLATILE;
|
LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Daysymetric Dot Density
|
||||||
|
--
|
||||||
|
-- @param geom: the geometry that has the
|
||||||
|
--
|
||||||
|
-- @param no_points: the total number of points to create
|
||||||
|
--
|
||||||
|
-- @param targetGeoms: the geometry that has the
|
||||||
|
--
|
||||||
|
-- @param weights: targetGeom weights
|
||||||
|
--
|
||||||
|
-- RETURNS setof points
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION CDB_DasymetricDotDensity(geom GEOMETRY, no_points NUMERIC, targetGeoms GEOMETRY[], weights numeric [])
|
||||||
|
RETURNS setof GEOMETRY
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'running Dasymetric';
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT cdb_crankshaft._CDB_WeightedDD(no_points, array_agg( ST_INTERSECTION(geom,g)), array_agg(ST_AREA(ST_INTERSECTION(geom,g))*w)::NUMERIC[])
|
||||||
|
FROM unnest(targetGeoms) as g , unnest(weights) as w
|
||||||
|
WHERE geom && g;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql;
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
WITH g AS (
|
|
||||||
SELECT ST_Buffer(ST_SetSRID(ST_MakePoint(0,0),4326)::geometry, 1000)::geometry AS g
|
|
||||||
),
|
|
||||||
points AS(
|
|
||||||
SELECT (
|
|
||||||
ST_Dump(
|
|
||||||
cdb_crankshaft.cdb_dot_density(g.g, 100)
|
|
||||||
)
|
|
||||||
).geom AS p FROM g
|
|
||||||
)
|
|
||||||
SELECT count(*), sum(CASE WHEN ST_Contains(g,p) THEN 1 ELSE 0 END) FROM points, g
|
|
||||||
count | sum
|
|
||||||
-------+-----
|
|
||||||
100 | 100
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
WITH g AS (
|
|
||||||
SELECT ST_Buffer(ST_SetSRID(ST_MakePoint(0,0),4326)::geometry, 1000)::geometry AS g
|
|
||||||
),
|
|
||||||
points AS(
|
|
||||||
SELECT (
|
|
||||||
ST_Dump(
|
|
||||||
cdb_crankshaft.cdb_dot_density(g.g, 100)
|
|
||||||
)
|
|
||||||
).geom AS p FROM g
|
|
||||||
)
|
|
||||||
|
|
||||||
SELECT count(*), sum(CASE WHEN ST_Contains(g,p) THEN 1 ELSE 0 END) FROM points, g
|
|
||||||
|
|||||||
Reference in New Issue
Block a user