va bene .. dato che è nelle unità della mappa questo dovrebbe essere abbastanza semplice, entro i limiti. Conosci già l'altezza dell'etichetta. Se fosse in punti sarebbe dipendente dalla scala.
Ciò presuppone una dimensione dell'etichetta fissa, quindi la sua efficacia dipende dall'uniformità delle etichette e dal fatto che si usi o meno un carattere proporzionale o a larghezza fissa (la larghezza fissa è più semplice: moltiplicare la lunghezza dell'etichetta per la dimensione dell'etichetta per ottenere la larghezza dell'etichetta).
Purtroppo questo non risponde alla tua domanda su come trovare effettivamente i limiti dell'etichetta come renderizzati .
hai 4 casi (NE, NW, SE, SW).
suppongo che il tuo tavolo assomigli a questo (scuse, alcuni nomi di campi sono diversi)
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;
Quindi, aggiungi 4 punti (tutti identici) ma con etichette nei 4 quadranti per rappresentare i 4 casi d'uso principali
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')
Ho usato CRS 27700 (0,0 in basso a sinistra, unità della mappa in m) Ho assunto un'etichetta larghezza 50, altezza 30 unità mappa.
-- 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);
Trasformazioni Affine
Un'altra possibilità è abbreviare tutte le linee principali, per dire l'80%.
- È possibile utilizzare ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) per spostare la riga sull'origine per ottenere geom_o
- usa ST_Scale (geom_o, 0.8,0.8) per ottenere geom_o_scaled
- quindi ritradurre usando ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) di nuovo nella posizione originale.
Potrebbe funzionare meglio, anche se non l'ho provato.