được rồi .. vì nó trong các đơn vị bản đồ nên điều này khá đơn giản, trong giới hạn. Bạn đã biết chiều cao của nhãn. Nếu nó ở điểm thì nó sẽ phụ thuộc vào quy mô.
Điều này giả định kích thước nhãn cố định, do đó, mức độ hoạt động của nó phụ thuộc vào mức độ đồng nhất của nhãn của bạn và bạn có sử dụng phông chữ theo tỷ lệ hoặc chiều rộng cố định hay không (chiều rộng cố định dễ dàng hơn - nhân chiều dài của nhãn với kích thước nhãn lấy chiều rộng nhãn).
Đáng buồn thay, điều này không trả lời câu hỏi của bạn về cách thực sự tìm thấy giới hạn của nhãn như được hiển thị .
bạn có 4 trường hợp (NE, NW, SE, SW).
tôi giả sử bảng của bạn trông như thế này (xin lỗi, một số tên trường là khác nhau)
CREATE TABLE points
(
uniq int PRIMARY KEY,
geom geometry(Point,27700),
label_x int,
label_y int,
labeltext character varying(100)
);
ALTER TABLE points
OWNER TO user;
GRANT ALL ON TABLE points TO user;
GRANT SELECT ON TABLE points TO public;
Tiếp theo, thêm 4 điểm (tất cả giống hệt nhau) nhưng có nhãn trong 4 góc phần tư để thể hiện 4 trường hợp sử dụng chính
insert into points values
(1,ST_SetSRID(ST_Point(1000,1000),27700),750,750,'123');
insert into points values(2,ST_SetSRID(ST_Point(1000,1000),27700),1250,1250,'456')
insert into points values
(3,ST_SetSRID(ST_Point(1000,1000),27700),750,1250,'456')
insert into points values
(4,ST_SetSRID(ST_Point(1000,1000),27700),1250,750,'789')
Tôi đã sử dụng CRS 27700 (0,0 ở phía dưới bên trái, đơn vị bản đồ tính bằng m) Tôi đã giả sử một nhãn có chiều rộng 50, chiều cao 30 đơn vị bản đồ.
-- SW use case
CREATE OR REPLACE VIEW leader_line_sw AS
SELECT
uniq,
ST_MakeLine(geom, ST_SetSRID(ST_MakePoint(label_x+50, label_y+30), 27700))::geometry(linestring, 27700) AS geom
FROM points
WHERE label_x IS NOT NULL AND
label_y<=ST_Y(geom) and label_x<=ST_X(geom);
-- SE use case
CREATE OR REPLACE VIEW leader_line_se AS
SELECT
uniq,
ST_MakeLine(geom, ST_SetSRID(ST_MakePoint(label_x, label_y-30), 27700))::geometry(linestring, 27700) AS geom
FROM points
WHERE label_x IS NOT NULL AND
label_y<=ST_Y(geom) and label_x>ST_X(geom);
-- NE use case
CREATE OR REPLACE VIEW leader_line_ne AS
SELECT
uniq,
ST_MakeLine(geom, ST_SetSRID(ST_MakePoint(label_x, label_y), 27700))::geometry(linestring, 27700) AS geom
FROM points
WHERE label_x IS NOT NULL AND
label_y>ST_Y(geom) and label_x>ST_X(geom);
-- NW use case
CREATE OR REPLACE VIEW leader_line_nw2 AS
SELECT
uniq,
ST_MakeLine(geom, ST_SetSRID(ST_MakePoint(label_x+50, label_y), 27700))::geometry(linestring, 27700) AS geom
FROM points
WHERE label_x IS NOT NULL AND
label_y>ST_Y(geom) and label_x<=ST_X(geom);
Biến đổi affine
Một khả năng khác là rút ngắn tất cả các dòng hàng đầu, để nói 80%.
- Bạn có thể sử dụng ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) để di chuyển dòng đến gốc để lấy geom_o
- sử dụng ST_Scale (geom_o, 0.8,0.8) để nhận geom_o_scaled
- sau đó truyền lại bằng ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) trở lại vị trí ban đầu.
Điều này có thể hoạt động tốt hơn, mặc dù tôi đã không thử nó.