okay .. da es sich um Karteneinheiten handelt, sollte dies innerhalb von Grenzen ziemlich einfach sein. Sie kennen bereits die Höhe des Etiketts. Wenn es in Punkten wäre, wäre es skalierungsabhängig.
Dies setzt eine feste Etikettengröße voraus. Wie gut dies funktioniert, hängt davon ab, wie einheitlich Ihre Etiketten sind und ob Sie eine proportionale Schriftart oder eine Schriftart mit fester Breite verwenden (feste Breite ist einfacher - multiplizieren Sie die Länge des Etiketts mit der Etikettengröße mit Holen Sie sich die Etikettenbreite).
Leider beantwortet dies nicht Ihre Frage, wie Sie die Grenzen des gerenderten Etiketts tatsächlich finden können .
Sie haben 4 Fälle (NE, NW, SE, SW).
Ich gehe davon aus, dass Ihre Tabelle so aussieht (Entschuldigung, einige Feldnamen sind unterschiedlich)
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;
Fügen Sie als Nächstes 4 Punkte (alle identisch) hinzu, jedoch mit Beschriftungen in den 4 Quadranten, um die 4 Hauptanwendungsfälle darzustellen
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')
Ich habe CRS 27700 verwendet (0,0 in links unten, Karteneinheiten in m). Ich habe eine Etikettenbreite von 50 und eine Kartenhöhe von 30 angenommen.
-- 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);
Affine Transformationen
Eine andere Möglichkeit besteht darin, alle führenden Linien auf 80% zu verkürzen.
- Sie können ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) verwenden, um die Linie zum Ursprung zu verschieben und geom_o zu erhalten
- Verwenden Sie ST_Scale (geom_o, 0.8,0.8), um geom_o_scaled zu erhalten
- dann mit ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) wieder an die ursprüngliche Position übersetzen.
Dies könnte besser funktionieren, obwohl ich es nicht ausprobiert habe.