tamam .. harita birimlerinde olduğu gibi, bu sınırlamalar dahilinde oldukça basit olmalıdır. Etiketin yüksekliğini zaten biliyorsunuz. Puanlar içinde olsaydı ölçeğe bağlı olurdu.
Bu, sabit bir etiket boyutu olduğunu varsaydığından, bunun ne kadar iyi çalıştığı, etiketlerinizin ne kadar düzgün olduğuna ve orantılı veya sabit genişlikli bir yazı tipi kullanıp kullanmayacağınıza bağlıdır (sabit genişlik daha kolaydır - etiketin uzunluğunu etiket boyutuyla çarpın etiket genişliğini edinin).
Ne yazık ki bu, etiketin oluşturulduğu gibi sınırlarını nasıl bulacağınız hakkındaki sorunuza cevap vermiyor .
4 vakanız var (NE, NW, SE, SW).
tablonuzun böyle göründüğünü varsayıyorum (özür dileriz, bazı alan adları farklıdır)
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;
Ardından, 4 ana kullanım örneğini temsil etmek için 4 nokta (hepsi aynı) ancak 4 çeyrekte etiketlerle ekleyin
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 kullandım (sol altta 0,0, m cinsinden harita birimleri) Etiket genişliği 50, yükseklik 30 harita birimleri varsaydım.
-- 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);
Afin Dönüşümler
Başka bir olasılık, tüm önde gelen hatları% 80 kısaltmaktır.
- Çizgiyi geom_o almak için başlangıç noktasına taşımak için ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) kullanabilirsiniz.
- geom_o_scaled almak için ST_Scale (geom_o, 0.8,0.8) kullanın
- daha sonra ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) kullanarak orijinal konumuna geri çevirin.
Denememiş olmama rağmen bu daha iyi olabilir.