Vale como está en unidades de mapa esto debería ser bastante sencillo, dentro de las limitaciones. Ya sabes la altura de la etiqueta. Si estuviera en puntos dependería de la escala.
Esto supone un tamaño de etiqueta fijo, por lo que su funcionamiento depende de la uniformidad de sus etiquetas y de si utiliza una fuente proporcional o de ancho fijo (el ancho fijo es más fácil: multiplique la longitud de la etiqueta por el tamaño de la misma para obtener su ancho).
Lamentablemente, esto no responde a su pregunta sobre cómo encontrar los límites de la etiqueta como se hace .
tienes 4 casos (NE,NW,SE,SW).
Supongo que su tabla tiene el siguiente aspecto (disculpas, algunos nombres de campos son diferentes)
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;
A continuación, añada 4 puntos (todos idénticos) pero con etiquetas en los 4 cuadrantes para representar los 4 casos de uso principales
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')
He utilizado el CRS 27700 (0,0 en la parte inferior izquierda, unidades del mapa en m) He asumido una etiqueta de ancho 50, altura 30 unidades de mapa.
-- 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);
Transformaciones afines
Otra posibilidad es acortar todas las líneas de dirección, por ejemplo al 80%.
- Puedes usar ST_Translate(geom,-ST_X(geom),-ST_Y(geom)) para mover la línea al origen y obtener geom_o
- utilice ST_Scale(geom_o,0.8,0.8) para obtener geom_o_scaled
- luego retranslada usando ST_Translate(geom_o_scaled,ST_X(geom),ST_Y(geom)) de vuelta a la posición original.
Esto podría funcionar mejor, aunque no lo he probado.
1 votos
Si se trata de unidades cartográficas, debería ser bastante fácil adivinar la altura y, por lo tanto, acortar la línea de referencia para compensar.)
0 votos
El tamaño de la etiqueta está en unidades de mapa.