Merge non-adjacent polygons in Qgis or Postgres - postgresql

I am working with Qgis and PostgreSQL. But i can't figure out how to merge the non-adjacent polygons in my screenshot into one record? Can anybody help mee with this problem?
I want all the polygons with the same cat to be merged in one record.
See screenshot here:
Thnx

If you want use Postgres you need create a SELECT using ST_Union
geometry ST_Union(geometry set g1field);
geometry ST_Union(geometry g1, geometry g2);
geometry ST_Union(geometry[] g1_array);
You can try this to create one array
Concatenate multiple rows in an array with SQL on PostgreSQL
I try this one in my states tables and work ok
SELECT ST_Union(a_geom)
FROM (SELECT array_agg(e.geom) as a_geom
FROM mapas.estadosven_region e
) t
I make another test and looks like this also may work
SELECT ID, ST_Union(geom)
FROM test_dissolve_function t
WHERE ST_isValid(geom)='t'
GROUP BY ID;

Related

ST_Intersects() query took too long

I'm working on a query using the PostGIS extension that implements a 'spatial join' work. Running the query took an incredibly long time and failed in the end. The query is as follows:
CREATE INDEX buffer_table_geom_idx ON buffer_table USING GIST (geom);
CREATE INDEX point_table_geom_idx ON point_table USING GIST (geom);
SELECT
point_table.*,
buffer_table.something
FROM
point_table
LEFT JOIN buffer_table ON ST_Intersects (buffer_table.geom, point_table.geom);
where the point_table stands for a table that contains over 10 million rows of point records; the buffer_table stands for a table that contains only one multi-polygon geometry.
I would want to know if there is anything wrong with my code and ways to adjust. Thanks in advance.
With a LEFT JOIN you're going through every single record of point_table and therefore ignoring the index. Try this and see the difference:
SELECT point_table.*
FROM point_table
JOIN buffer_table ON ST_Contains(buffer_table.geom, point_table.geom);
Divide and conquer with ST_SubDivide
Considering the size of your multipolygon (see comments), it might be interesting to divide it into smaller pieces, so that the number of vertices for each containment/intersection calculation also gets reduced, consequently making the query less expensive.
First divide the large geometry into smaller pieces and store in another table (you can also use a CTE/Subquery)
CREATE TABLE buffer_table_divided AS
SELECT ST_SubDivide(geom) AS geom FROM buffer_table
CREATE INDEX buffer_table_geom_divided_idx ON buffer_table_divided USING GIST (geom);
.. and perform your query once again against this new table:
SELECT point_table.*
FROM point_table
JOIN buffer_table_divided d ON ST_Contains (d.geom, point_table.geom);
Demo: db<>fiddle

How to find the nearest point Postgis

I have two tables in Postgis. Table of plats and table of kindergartens...
I would like to find the closest kindergraten from the given plat (ogc_fid=1397632) from another table. Both of them are points. I have tried something like that, but it still loading the result, probably something is wrong...
SELECT
name
FROM
kindergarten, plats
ORDER BY
ST_Transform(kindergarten.geom,5514) <->
(SELECT geom FROM plats where ogc_fid=1397632)
LIMIT 1;
Im not sure if can be a problem that table plats has SRID (Geometry(point,5514)) and table kindergartens has SRID (Geometry(point,3857) Those has been imported from OSM). Does it have some role that SRID is changed in SQL query and not before running them itself?
Do some of you know where is the problem? Im a beginner in spatial queries...
Thank you very much.

Best way to run ST_intersects on features inside one table?

I have a table of LineString features and I wish to identify which lines intersect.
ST_Intersects(geom1, geom2) needs two geometries from two different tables. Right now i am creating two different references back to the same table and it just doesn't seem like the right approach.
I am currently using the following bit of code, and I am curious if there is some better way of accomplishing this. Surely running an intersect on features within one table must be a common task.
SELECT a.link_id as a_link_id,
b.link_id as b_link_id,
st_intersects(a.geom, b.geom)
INTO results_table
FROM table_one a, table_one b
WHERE a.link_id != b.link_id;
PostGIS 2.4.0
PG 9.6.5
Your approach is ok. The only problem with this is that it will return duplicate records. e.g if two lines are intersecting with IDs 10 and 11 respectively. There will be two rows for each ID in the result, even the lines are intersecting only once. You can cater this with > or < operator in place of !=. And intersect condition comes in where i guess
SELECT a.link_id as a_link_id,
b.link_id as b_link_id
INTO results_table
FROM table_one a, table_one b
WHERE a.link_id < b.link_id AND st_intersects(a.geom, b.geom)

ST_contains taking too much time

I am trying to match latitude/longitude to a particular neighbor location using below query
create table address_classification as (
select distinct buildingid,street,city,state,neighborhood,borough
from master_data
join
Borough_GEOM
on st_contains(st_astext(geom),coordinates) = 'true'
);
In this, coordinates is of below format
ST_GeometryFromText('POINT('||longitude||' '||latitude||')') as coordinates
and geom is of column type geometry.
i have already created indexes as below
CREATE INDEX coordinates_gix ON master_data USING GIST (coordinates);
CREATE INDEX boro_geom_indx ON Borough_GEOM USING gist(geom);
I have almost 3 million records in the main table and 200 geometric information in the GEOM table. Explain analyze of the query is taking so much time (2 hrs).
Please let me know, how can i optimize this query.
Thanks in advance.
As mentioned in the comments, don't use ST_AsText(): that doesn't belong there. It's casting the geom to text, and then going back to geom. But, more importantly, that process is likely to fumble the index.
If you're unique on only column then use DISTINCT ON, no need to compare the others.
If you're unique on the ID column and your only joining to add selectivity then consider using EXISTS. Do any of these columns come from the borough_GEOM other than geom?
I'd start with something like this,
CREATE TABLE address_classification AS
SELECT DISTINCT ON (buildingid),
buildingid,
street,
city,
state,
neighborhood,
borough
FROM master_data
JOIN borough_GEOM
ON ST_Contains(geom,coordinates);

How do I use ST_Contains in following case?

I have two tables. First with points, and second with polygons. I need to find out which points are in required polygon according to the attribute gid.
Using query: SELECT table1.* FROM table1, table2 WHERE table2.gid=1 AND ST_Contains(table2.geom2, table1.geom1);
What I get is empty table (only columns without data)...
Tnx
Are you sure there are any intersecting points? Try
SELECT COUNT(*) FROM table2 WHERE table2.gid=1
It should return 1.
Another thing you could try is using ST_Intersects instead of ST_Contains.
Otherwise, you might need to post some data dumps of data you think should match.