わかりました。マップ単位なので、制限内でこれはかなり簡単なはずです。あなたはすでにラベルの高さを知っています。それがポイントである場合、それはスケールに依存します。
これは固定ラベルサイズを想定しているため、これがどの程度うまく機能するかは、ラベルの均一性と、プロポーショナルフォントまたは固定幅フォントを使用するかどうかによって決まります(固定幅の方が簡単です。ラベルの長さにラベルサイズを掛けると、ラベルの幅を取得します)。
残念ながら、これは実際にレンダリングされたラベルの境界を見つける方法についてのあなたの質問に答えません。
あなたには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);
アフィン変換
別の可能性は、すべての先行線を短くすることです。
- 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))を使用して元の位置に再変換します。
これは試したことはありませんが、うまくいくかもしれません。