Daha çox

Dinamik lider xətləri necə yaradılır?


QGIS "Move Label" alətinə əlavə olaraq PostGIS görünüşü istifadə edərək dinamik lider xətləri yaratmağa çalışıram.

SEÇİN OLARAQ GÖRÜNTÜLÜK LİDERİ_XƏTİ YARADIN, ST_MakeLine (geom, ST_SetSRID (ST_MakePoint (xcord_label, ycord_label), SRID)) :: geometry (linestring, SRID) AS geom from FROM xCord_label boş deyil;

Bu, bütün etiketlər üçün yaxşı işləyirST_X (geom) lakin etiketlər üçün səhv görünən lider xətləri yaradırST_X (geom)> xcord_label.

Kimsə etiket üçün düzgün yerləşdirilmiş lider xəttlərini necə əldə edəcəyini bilirmi?ST_X (geom)> xcord_label? Etiketlərin xmax koordinatına müraciət etməyin bir yolu varmı?


Daha yaxşı bir etiket yerləşdirmək üçün xəttin azimutundan təyin olunmuş QGIS 'kvadrant yerləşdirmə göstəricisindən istifadə edə bilərsiniz. Quadrant bir nöqtə ətrafında 8 mövqeyi göstərir:

[0 = Soldan yuxarıda | 1 = yuxarıda 2 = Sağda | 3 = Sol | 4 = bitdi | 5 = Sağ | 6 = Soldan Aşağıda | 7 = Aşağıda | 8 = Sağda]

Budur Null Adası ətrafında bir masa və iki baxış yaradan bir nümunə.

CƏDVƏL nöqtələrini YARAT (gid serial PRIMARY KEY, geom həndəsəsi (Point, 4326), label_geom həndəsəsi (Point, 4326), etiket mətni); INSERT INTO xal (geom, label_geom, etiket) SEÇİN mənşəyi, pt, dəyirmi (dərəcələr (ST_Azimuth (mənşə, pt))) || 'dərəcə' FROM (SEÇİN ST_SetSRID (ST_MakePoint (0, 0), 4326) AS mənşəli, ST_SetSRID (ST_MakePoint (cos (radians (x)), sin (radians (x))), 4326) AS pt FROM generate_series (0, 350, 15) AS x) AS f; ST_Azimuth (geom, label_geom) ISNULL OLDUĞUNUNDA SEÇİN OLARAK GÖRÜNTÜ ETKİNLƏRİNİ YARADIN VƏ DEĞİŞDİNİZ, ST_Azimuth (geom, label_geom) ISNULL ONDA 2 - azimut müəyyənləşə bilmədikdə default (ST_Azimuth (geom, label_geom)) <22.5 ONDAN 1 - WHEN dərəcə (ST_Azimuth (geom, label_geom)) <67.5 THEN 2 - WHEN dərəcədən yuxarı (ST_Azimuth (geom, label_geom)) <112.5 THEN 5 - Sağ WHEN dərəcə (ST_Azimuth (geom, label_geom)) <157.5 THEN 8 - WHEN dərəcəsindən (ST_Azimuth (geom, label_geom)) <202.5 THEN 7 - WHEN dərəcədən aşağı (ST_Azimuth (geom, label_geom)) <247.5 THEN 6 - WHEN dərəcədən aşağıda (ST_Azimuth (geom, label_geom)) <292.5 THEN 3 - WHEN dərəcə solunda (ST_Azimuth (geom, label_geom)) <337.5 THEN 0 - Sol yuxarıda ELSE 1 -> = 337.5 Kvadrat kimi SONDAN yuxarıda, nöqtələrdən etiket; SELECT GID, ST_MakeLine (geom, label_geom) :: geometry (LineString, 4326) AS geom, etiket FROM nöqtələrindən GÖRÜNÜŞÜN BAŞLADIQ VƏ YERİNİ DƏYİŞİN;

Sonra QGIS-də əlavə edin:

  • xal-geom
  • lider_sətir-geom- əsas açar olmalıdırgid
  • nöqtə_işarələri-geom- əsas açar olmalıdırgid

İndi üçün qat xüsusiyyətlərini konfiqurasiya edinnöqtə_işarələri:

  • Nöqtənin çəkilməməsi üçün üslubu dəyişdirin, məsələn, ölçüsü 0.0-a dəyişdirin
  • Bu qatı etiketləyinetiketvə atribut sahəsini istifadə etmək üçün "Quadrant" ı dəyişdirərək yerləşdirməni "Nöqtədən ofset" olaraq dəyişdirinkvadrant

Bingo!

Üçün bir az fərqli bir yanaşma tələb olunduğunu unutmayıncoğrafiyanövlər, çünki ST_Azimuth fərqli davranır.


Yeniləmə: Yeni xal əlavə edərkənxalqat, thegeomsahə həmişəki kimi yenilənir, ammaetiket_geomdeyil. Varsayılan dəyəri doldurmaq üçünetiket_geomyeni nöqtələrlə, bir tetikleyici yaradılmalıdır. Ancaq bir tetikleyici funksiyasından istifadə olunursakvadrantgöstərici saxlanıla bilərxalmasa vənöqtə_işarələrigörünüşü laqeyd etmək olar:

Məsələn, bir masa və bir görünüş ilə bir az fərqli bir nümunə ilə yenidən başlayaq:

- CƏDVƏL BAKIŞLARINI KASKADA; CƏDVƏL nöqtələrini YARAT (gid serial PRIMARY KEY, geom həndəsəsi (Point, 4326), label_geom həndəsəsi (Point, 4326), kvadrant tam ədədi, etiket mətni); FUNCTION YARATDIN label_geom_tg_fn () RETURNS tetikleyiciyi $ BODY $ DECLARE azimuth float8; BAŞLAYIN - Varsayılan bir etiket_geom təyin edin YENİ.label_geom ISNULL THEN NEW.label_geom: = NEW.geom; SONDUR; - Kvadrant azimutunu təyin edin: = dərəcə (ST_Azimuth (NEW.geom, NEW.label_geom)); NEW.quadrant: = Azimut ONDAN 2 - azimut təyin oluna bilmədiyi hal, azimut <22.5 THEN 1 - Azimut <67.5 THEN 2 - Azimut <67.5 THEN 2 - Azimut <112.5 THEN 5 - Sağ NƏZIMUT <157.5 THEN 8 - Nə zaman azimut <202.5 THEN 7 - azimut olduqda <247.5 THEN 6 - Azimut <292.5 THEN 3 - Azimut <337.5 THEN 0 - SİZDƏSİ YAXI 1 SON; -> = 337.5 YUKARIDA YENİ; SON; $ BODY $ LANGUAGE plpgsql; HƏR SIRA İCRA PROSEDÜRÜ ÜÇÜN XALLARA TƏKLİ VƏ YENİLƏNMƏDƏN ƏVVƏL TRIGGER label_geom_tg yaradın label_geom_tg_fn ();

İlk nümunədən, yenidən edinXallara əlavə edinLİDER_LAYINI GÖRÜNÜŞÜ VƏ YA DAĞITINifadələr, çünki bunlar dəyişiklik tələb etmir. Ancaq buna əhəmiyyət verməyinlider_sətirbaxış.

Sonra QGIS-də əlavə edin:

  • xal-geom
  • xal-etiket_geom
  • lider_sətir-geom- əsas açar olmalıdırgid

İndi üçün qat xüsusiyyətlərini konfiqurasiya edinxaliləetiket_geomilk nümunə kiminöqtə_işarələri. Thekvadrantspesifikator yeni və köçürülmüş nöqtələr üçün avtomatik olaraq dəyişdiriləcək, ancaq bu dəyişiklikləri yalnız düzəlişlərinizi hər dəfə saxladığınız zaman görəcəksiniz.


tamam ... xəritə vahidlərində olduğu kimi bu məhdudiyyətlər daxilində kifayət qədər düz olmalıdır. Etiketin hündürlüyünü artıq bilirsiniz. Xallarda olsaydı, miqyasdan asılı olardı.

Bu sabit bir etiket ölçüsünü nəzərdə tutur, buna görə bunun nə dərəcədə yaxşı işləməsi etiketlərin nə qədər vahid olduğundan və mütənasib və ya sabit genişlikli bir şrift istifadə edib etməməyinizdən asılıdır (sabit genişlik daha asandır - etiket uzunluğunu etiket ölçüsünə vurun etiket genişliyini əldə edin).

Təəssüf ki, bu etiketin hüdudlarını necə tapmaq barədə sualınıza cavab vermir göstərildiyi kimi.

4 halınız var (NE, NW, SE, SW).

masanızın belə göründüyünü düşünürəm (üzr istəyirəm, bəzi sahə adları fərqlidir)

CƏDVƏL nöqtələrini YARADIN (uniq int PRIMARY KEY, geom həndəsəsi (Point, 27700), label_x int, label_y int, dəyişən etiket mətni xarakteri (100)); ALTER CƏDVƏLİ istifadəçiyə sahibdir; BÜTÜNÜ MƏSƏLƏDƏ istifadəçiyə verin; CƏDVƏL ÜÇÜN İSTƏNİLƏN İSTƏNİLƏNLƏRİ ictimaiyyətə təqdim edin;

Ardından, 4 əsas istifadə vəziyyətini təmsil etmək üçün 4 xalla (hamısı eyni), lakin 4 dörddə bir etiketlə əlavə edin

bal dəyərlərinə daxil edin (1, ST_SetSRID (ST_Point (1000,1000), 27700), 750,750, '123'); bal dəyərlərinə daxil edin (2, ST_SetSRID (ST_Point (1000,1000), 27700), 1250,1250, '456') bal dəyərlərinə daxil edin (3, ST_SetSRID (ST_Point (1000,1000), 27700), 750,1250, '456') nöqtə dəyərlərinə daxil edin (4, ST_SetSRID (ST_Point (1000,1000), 27700), 1250,750, '789')

CRS 27700 istifadə etdim (solda 0,0, m-də xəritə vahidləri) Etiket eni 50, hündürlüyü 30 xəritə vahidi qəbul etdim.

- SW istifadə vəziyyəti YARADIN VƏ GÖRÜNMƏYİNİ BAĞLAYIN lideri_line_sw OLARAQ SEÇİN uniq, ST_MakeLine (geom, ST_SetSRID (ST_MakePoint (label_x + 50, label_y + 30), 27700)) :: geometry (linestring, 27700) AS geom from AS from label_x NULL AND etiket_y <= ST_Y (geom) və label_x <= ST_X (geom); - SE istifadə vəziyyəti YARATIN VƏ GÖRÜNMƏNİN BAŞLADIĞINIZ SEÇİN unik, ST_MakeLine (geom, ST_SetSRID (ST_MakePoint (label_x, label_y-30), 27700)) :: geometry (linestring, 27700) AS geom, etiket_x boş olduğu yerlərdən label_y <= ST_Y (geom) və label_x> ST_X (geom); - NE case case YARADIN VƏ DEĞİŞTİRİN lideri_line_ne AS SELECT uniq, ST_MakeLine (geom, ST_SetSRID (ST_MakePoint (label_x, label_y), 27700)) :: həndəsə (linestring, 27700) AS geom, etiket_x NULL VƏ etiketli deyil> ST_Y (geom) və label_x> ST_X (geom); - NW case case YARADIN VƏ DEĞİŞTİRİN lideri_line_nw2 AS SELECT uniq, ST_MakeLine (geom, ST_SetSRID (ST_MakePoint (label_x + 50, label_y), 27700)) :: geometry (linestring, 27700) AS geom from NO from NULL AND AND NULL AND label_y> ST_Y (geom) və label_x <= ST_X (geom);

Afin Transformasiyaları

Başqa bir ehtimal, bütün aparıcı xətləri, yəni% 80-i qısaltmaqdır.

  • Geom_o almaq üçün xətti mənşəyə aparmaq üçün ST_Translate (geom, -ST_X (geom), - ST_Y (geom)) istifadə edə bilərsiniz.
  • geom_o_ miqyasını almaq üçün ST_Scale (geom_o, 0.8,0.8) istifadə edin
  • sonra ST_Translate (geom_o_scaled, ST_X (geom), ST_Y (geom)) istifadə edərək yenidən orijinal vəziyyətinə qaytarın.

Bu daha yaxşı işləyə bilər, baxmayaraq ki, sınamamışam.