What I basically want is:
I want to have the polygon which is numbered as 13. As you can see there are many overlapping polygons but the most overlapping one is numbered 13. The image is from this answer.
Also there is one another question on stackexchange that is related to my question.
In my case I have these polygons:
And I need the red part.
What I have tried so far is this:
WITH pois AS (
SELECT unnest(ARRAY['1','2','3','4','5','6','7']) AS id, unnest(ARRAY[41.720302,41.732075701,41.727253557,41.7503713,41.723427674,41.786769,41.77869826276586]) AS lat, unnest(ARRAY[38.488551,38.525743929,38.5174403600001,38.397713078,38.4954947360001,38.605068,38.4268728196621]) AS lon
ORDER BY id ASC
), buffers AS (
SELECT id, ST_Transform(ST_Buffer(ST_Transform(ST_SetSRID(ST_Point(lon, lat), 4326), 5275), 3000), 4326) buff, ST_SetSRID(ST_Point(lon, lat), 4326) pt
FROM pois
), nodes AS (
SELECT MAX(id) as id, (ST_Dump(ST_Node(ST_Collect(ST_ExteriorRing(buff))))).geom AS geom
FROM buffers
)
SELECT ,
ST_Difference(
geom, (
SELECT ST_Union(buff)
FROM buffers
WHERE
buffers.id = ANY(z.ids) AND
z.id != buffers.id
)
)
FROM (
SELECT count() AS count, array_agg(c.id) ids, p.id, ST_GeomFromText(MAX(ST_AsEWKT(p.buff))) geom, p.pt
FROM buffers p
JOIN buffers c
ON ST_Contains(c.buff, ST_PointOnSurface(p.buff))
GROUP BY (p.id, p.pt)
ORDER BY count ASC
) AS z
WHERE count > 1
EDIT
So turns out, in python I can iteratively intersect areas, it maybe slower than some database query but looks like it gets work done. It is hard to make this example into a working code without my database and modules but at least it may give some ideas to other people out there and it also is not optimized by any means at this state:
targets = {
b_id: {
"point": GEOSPoint(i["lat"], i["lon"], srid=4326),
"buffer": BufferAnalysis.create_buffer(i["lat"], i["lon"], distance / 1000)
} for b_id, i in df.iterrows()
}
sections = set()
for b_id, polygon in targets.items():
intersections = []
for sub_id, sub_polygon in targets.items():
if polygon["buffer"] & sub_polygon["buffer"] and id != sub_id:
intersections.append([sub_id, sub_polygon])
if len(intersections) > 1:
for i in range(len(intersections), 1, -1):
tmp_poly = polygon["buffer"]
areas = intersections[:i]
info = "|".join(set([i[0] for i in areas] + [b_id]))
if info not in sections:
print(b_id, info)
sections.add(info)
for sub_id, sub_polygon in areas:
tmp_poly = tmp_poly.intersection(sub_polygon["buffer"])
I added sections and range selection with length of intersections are just to get other intersections like, 4 regions were to intersect but there are other combinations 3 regions in these 4 regions, it is not correct in this example but at least it gives me the most intersecting area. If I come up with a better idea, I will add it here.


