好吧..因为它以地图单位为单位,所以在限制范围内应该相当简单。您已经知道标签的高度。如果说得对,那将取决于规模。
假设标签尺寸固定,因此效果如何取决于标签的均匀程度以及是否使用比例或固定宽度的字体(固定宽度比较容易-将标签的长度乘以标签尺寸即可获取标签宽度)。
遗憾的是,这并没有回答您关于如何实际找到所渲染标签边界的问题。
您有4种情况(NE,NW,SE,SW)。
我认为您的表格看起来像这样(抱歉,某些字段名称不同)
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;
接下来,添加4个点(全部相同),但在4个象限中带有标签以表示4个主要用例
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')
我使用了CRS 27700(0,0在左下,地图单位为m),我假设标签的宽度为50,高度为30。
-- 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);
仿射变换
另一种可能性是缩短所有领先优势,例如缩短80%。
- 您可以使用ST_Translate(geom,-ST_X(geom),-ST_Y(geom))将线移动到原点以获取geom_o
- 使用ST_Scale(geom_o,0.8,0.8)获得geom_o_scaled
- 然后使用ST_Translate(geom_o_scaled,ST_X(geom),ST_Y(geom))重新转换回原始位置。
尽管我还没有尝试过,但这可能会更好。