Cách nhân rộng Giao diện ArcGIS trong PostGIS


8

Tôi đang cố gắng sao chép quy trình ArcGIS này trong PostGIS: http://bloss.esri.com/esri/arcgis/2012/11/13/spaghetti_and_meatballs/ . Phần này mô tả cách chia điểm đệm thành đa giác dựa trên giao điểm của chúng, đếm số lớp và quy kết nó cho đa giác để phân loại chúng. Tôi đang sử dụng nó để tạo một bản đồ mật độ điểm thô với các vectơ và kết quả thật tuyệt vời cho dữ liệu của tôi được đặt trong ArcGIS. Tuy nhiên, tôi đang vật lộn để tìm ra thứ gì đó khả thi trong PostGIS nơi tôi cần nó để tạo các lớp mật độ điểm động cho bản đồ web.

Trong ArcGIS, tôi chỉ cần chạy công cụ Intersect trên lớp điểm đệm của mình để tạo các hình dạng tôi cần.

Trong PostGIS, tôi đã chạy truy vấn này:

CREATE TABLE buffer_table AS SELECT a.gid AS gid, ST_Buffer(a.geo,.003) AS geo FROM public.pointTable a;

CREATE TABLE intersections AS SELECT a.gid AS gid_a, b.gid AS gid_b, ST_Intersection(a.geo,b.geo) AS geo FROM public.pointTable a, public.pointTable b WHERE ST_Intersects(a.geo, b.geo) AND a.gid < b.gid;

DELETE FROM intersections WHERE id_a = id_b;

Đầu ra trông khá giống với đầu ra ArcGIS, ngoại trừ việc nó không phá vỡ các đa giác xuống cùng mức cần thiết cho một bản đồ mật độ có ý nghĩa. Dưới đây là ảnh chụp màn hình những gì tôi muốn nói:

ArcGIS PostGIS

ArcGIS ở bên trái và PostGIS ở bên phải. Hơi khó để nói, nhưng hình ảnh ArcGIS cho thấy đa giác 'bên trong' được tạo ra nơi cả 3 bộ đệm giao nhau. Mặt khác, đầu ra PostGIS không tạo ra đa giác bên trong đó và thay vào đó nó giữ nguyên các thành phần của nó. Điều này làm cho không thể cung cấp một phân loại cho chỉ khu vực bên trong đó với 3 lớp chồng lên nhau so với chỉ 1 cho các phần bên ngoài.

Có ai biết bất kỳ chức năng PostGIS nào để phá vỡ đa giác xuống mức tôi cần không? Ngoài ra, có ai biết một cách tốt hơn để tạo ra một bản đồ mật độ điểm với các vectơ trong PostGIS không?

Câu trả lời:


9

Bạn có thể làm tất cả điều này trong một bước bằng cách kết nối các CTE lại với nhau, nhưng tôi đã thực hiện nó trong một số để tôi có thể xem kết quả trong QGIS khi tôi tiến triển.

Đầu tiên, tạo ra một loạt các điểm ngẫu nhiên để làm việc, sử dụng phân phối gaussian để chúng ta có nhiều sự chồng chéo ở giữa.

create table pts as with 
    rands as (
        select generate_series as id, random() as u1, random() as u2 
        from generate_series(1,100))
select
      id,
      st_setsrid(st_makepoint(
            50 * sqrt(-2 * ln(u1)) * cos(2*pi()*u2), 
            50 * sqrt(-2 * ln(u1)) * sin(2*pi()*u2)),4326) as geom
from rands;

Bây giờ đệm các điểm thành các vòng tròn để chúng ta có được một số chồng chéo.

create table circles as
    select id, st_buffer(geom, 10) as geom from pts;

Bây giờ, chỉ trích xuất các ranh giới từ các vòng tròn. Nếu bạn có đa giác có lỗ, bạn sẽ phải sử dụng ST_DumpRings () và trở nên lạ mắt hơn ở đây. Tôi có đa giác đơn giản nên tôi gian lận. Một khi bạn có ranh giới, liên kết chúng với chính chúng (thực ra là bất kỳ phần nhỏ nào của sự trùng hợp ngẫu nhiên sẽ làm) để buộc chúng phải gật đầu và lặp lại. (Đây là phép thuật.)

create table boundaries as
    select st_union(st_exteriorring(geom)) as geom from circles;

Bây giờ xây dựng lại các khu vực bằng cách sử dụng các đường kẻ gật đầu. Đây là khu vực bị phá vỡ, chỉ có một đa giác trên mỗi khu vực. Sau khi đa giác hóa, đổ các đa giác riêng lẻ ra khỏi đầu ra đa giác.

create sequence polyseq;

create table polys as
    select 
        nextval('polyseq') as id, 
        (st_dump(st_polygonize(geom))).geom as geom 
    from boundaries;

Bây giờ, thêm một vị trí cho số lượng đa giác và điền vào nó bằng cách nối các tâm của đa giác cắt nhỏ vào các vòng tròn ban đầu và tóm tắt cho từng mảnh nhỏ. Đối với dữ liệu lớn hơn, chỉ mục trên bảng vòng tròn ít nhất sẽ được yêu cầu để làm cho mọi thứ không bị chậm một cách khó tin.

create index circles_gix on circles using gist (geom);

alter table polys add column count integer default 0;

update polys set count = p.count 
from (
    select count(*) as count, 
           p.id as id 
    from polys p 
    join circles c 
    on st_contains(c.geom, st_pointonsurface(p.geom)) 
    group by p.id
) as p
where p.id = polys.id;

Đó là nó, bây giờ bạn không có đa giác chồng chéo, nhưng mỗi đa giác kết quả có một số đếm trên đó cho biết có bao nhiêu trùng lặp.


Điều đó rất ấn tượng. Cuối cùng tôi đã sử dụng một chút phương pháp gian lận hoạt động và với tập dữ liệu cụ thể của tôi (có thể cũng ít tốn tài nguyên hơn, điều này rất quan trọng đối với dự án của tôi liên quan đến lập bản đồ web). Tôi sẽ đăng giải pháp của mình như một phương pháp thay thế để tạo ra bản đồ nhiệt, nhưng đây là câu trả lời chính xác cho câu hỏi tôi đã hỏi.
scavok

2

Phương pháp cuối cùng tôi sử dụng là tạo lưới fishnet trong khu vực tôi quan tâm với "độ phân giải" đủ cao để tạo kiểu và phản ánh dữ liệu ở mức độ hợp lý. Bạn có thể đọc về chức năng fishnet ở đây: Làm thế nào để tạo lưới đa giác thông thường trong PostGIS?

CREATE TABLE fishnet AS
SELECT * FROM ST_CreateFishnet(800,850,.0005,.0005,-104.9190,38.7588);

Điều này tạo ra fishnet với 800 hàng, 850 cột, có chiều cao và chiều dài 0,0005 radian (sử dụng phép chiếu WGS84 trong lat / long và phạm vi địa lý đủ nhỏ để độ méo không đáng kể - tức là tất cả chúng đều bị biến dạng ít nhiều bằng nhau ), và sau đó tọa độ cho phía dưới bên trái của lưới.

UPDATE fishnet SET geom = ST_SetSRID(geom,4326);
CREATE INDEX fishnet_geom ON fishnet USING gist (geom);
ANALYZE fishnet;

Bởi vì điều này tạo ra một số lượng lớn các đa giác sẽ có các truy vấn chạy trên chúng, tôi đã tạo một chỉ mục và cập nhật số liệu thống kê. Điều này đã giảm các truy vấn thông thường của tôi từ hơn 50 giây xuống còn 4-5 giây.

SELECT ST_Union(a.geom), a.count
FROM (SELECT count(*) as count, fishnet.geom as geom
    FROM fishnet, incidents
    WHERE ST_DWithin(incidents.geo,fishnet.geom,.002) AND (incidents.incidenttype = 'Burglary')
    GROUP BY fishnet.geom) a
WHERE a.count >= 3
GROUP BY a.count;

Truy vấn con ở đây tính số lượng sự cố trong khoảng 0,002 radian (khoảng 220 mét) của mỗi đa giác lưới fishnet, và nhóm chúng theo lưới fishnet. Điều này có hiệu quả đếm số vòng tròn chồng chéo với độ phân giải của lưới.

Truy vấn bên ngoài tôi đã sử dụng để Liên kết giá trị đếm của mỗi đa giác và giới hạn số đếm là 3 hoặc cao hơn. Mặc dù liên minh không thực sự cần thiết và là phần tốn nhiều tài nguyên nhất của truy vấn, nhưng điều quan trọng đối với ánh xạ web là nó có hiệu quả biến hàng chục ngàn đa giác lưới, hoạt động không tốt khi phục vụ trực tiếp cho trình mở, vào tuy nhiên có nhiều giá trị đếm khác nhau (thường là vài chục cho dữ liệu của tôi).

Hạn chế giá trị đếm là một khả năng quan trọng đối với bản đồ nhiệt để chúng không mô tả quá nhiều dữ liệu đến mức không thể giải thích nó - nó cũng có thêm tiện ích tăng tốc truy vấn đáng kể.

Kết quả cuối cùng: bản đồ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.