oke .. karena ada di unit peta ini harus cukup mudah, dalam batasan. Anda sudah tahu ketinggian label. Jika dalam poin itu akan tergantung pada skala.
Ini mengasumsikan ukuran label tetap, jadi seberapa baik ini bekerja tergantung pada seberapa seragam label Anda, dan apakah Anda menggunakan font proporsional atau lebar-lebar (lebar tetap lebih mudah - gandakan panjang label dengan ukuran label ke dapatkan lebar label).
Sayangnya ini tidak menjawab pertanyaan Anda tentang cara menemukan batas-batas label yang diberikan .
Anda memiliki 4 kasing (NE, NW, SE, SW).
saya berasumsi meja Anda terlihat seperti ini (permintaan maaf, beberapa nama bidang berbeda)
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;
Selanjutnya, tambahkan 4 poin (semua identik) tetapi dengan label di 4 kuadran untuk mewakili 4 kasus penggunaan utama
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')
Saya menggunakan CRS 27700 (0,0 di kiri bawah, unit peta dalam m) Saya telah mengasumsikan label lebar 50, tinggi 30 unit peta.
-- 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);
Transformasi Affine
Kemungkinan lain adalah memperpendek semua lini terkemuka, katakanlah 80%.
- Anda dapat menggunakan ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) untuk memindahkan garis ke asal untuk mendapatkan geom_o
- gunakan ST_Scale (geom_o, 0.8.0.8) untuk mendapatkan geom_o_scaled
- kemudian menerjemahkan kembali menggunakan ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) kembali ke posisi semula.
Ini mungkin bekerja lebih baik, walaupun saya belum mencobanya.