16.5. Lesson: Construirea Geometriei

În această secțiune vom intra în detalii despre cum sunt construite geometriile în SQL. În realitate, probabil veți utiliza un GIS cum ar fi QGIS pentru creearea geometriilor complexe folosind instrumentele acestora; cu toate acestea, întelegerea modului cum sunt stocate poate fi utilă pentru scrierea de interogări și înțelegerea modului cum este alcătuită baza de date.

Scopul acestei lecții: De a înțelege mai bine cum să creați entități spațiale direct în PostgreSQL/PostGIS.

16.5.1. Crearea Șirurilor de Linii

Întorcându-ne la baza de date address, să facem tabelul de străzi să se potrivească cu celelalte; de ex., să aibă o constrângere pentru geometrie, un index și o intrare în tabelul geometry_columns.

16.5.2. Try Yourself moderate

  • Modificați tabela streets, astfel încât ea să aibă o coloană de geometrie de tipul ST_LineString.

  • Nu uitați să faceți actualizarea coloanelor de geometrie!

  • De asemenea, adăugați o constrângere pentru a preveni adăugarea geometrii care nu sunt null sau de tip LINESTRINGS.

  • Creați un index spațial în noua coloană de geometrie

Now let’s insert a linestring into our streets table. In this case we will update an existing street record:

update streets
set the_geom = 'SRID=4326;LINESTRING(20 -33, 21 -34, 24 -33)'
where streets.id=2;

Aruncați o privire la rezultatele din QGIS. (Poate fi necesar să faceți clic-dreapta pe stratul străzilor din panoul «Straturilor», apoi alegeți «Transfocare la extinderea stratului».)

Acum, creați mai multe intrări de străzi - unele în QGIS, iar altele din linia de comandă.

16.5.3. Crearea Poligoanelor

Creating polygons is just as easy. One thing to remember is that by definition, polygons have at least four vertices, with the last and first being co-located:

insert into cities (name, the_geom)
values ('Tokyo', 'SRID=4326;POLYGON((10 -10, 5 -32, 30 -27, 10 -10))');

Notă

Un poligon necesită acolade duble în jurul listei sale de coordonate; aceasta pentru a permite poligoane complexe având multiple zone neconectate. De exemplu

insert into cities (name, the_geom)
values ('Tokyo Outer Wards',
        'SRID=4326;POLYGON((20 10, 20 20, 35 20, 20 10),
                           (-10 -30, -5 0, -15 -15, -10 -30))'
        );

Dacă ați urmat acest pas, puteți verifica rezultatul prin încărcarea setului de date orașe în QGIS, deschizând tabelul de atribute al acestuia, și selectând noua intrare. Remarcați cum cele două noi poligoane se comportă ca unul singur.

16.5.4. Exercițiu: Learea Orașelor de Persoane

Pentru acest exercițiu ar trebui să faceți următoarele:

  • Ștergeți toate datele din tabela de personal.

  • Adăugați o coloană de cheie străină în tabela de personal, care face referire la cheia primară a tabelei orașelor.

  • Utilizați QGIS pentru a captura unele orașe.

  • Utilizați SQL pentru a introduce câteva înregistrări de personal, verificând că fiecare are asociate o stradă și un oraș.

Your updated people schema should look something like this:

\d people

Table "public.people"
   Column   |         Type          |                      Modifiers
 -----------+-----------------------+--------------------------------------------
  id        | integer               | not null
            |                       | default nextval('people_id_seq'::regclass)
  name      | character varying(50) |
  house_no  | integer               | not null
  street_id | integer               | not null
  phone_no  | character varying     |
  the_geom  | geometry              |
  city_id   | integer               | not null
Indexes:
  "people_pkey" PRIMARY KEY, btree (id)
  "people_name_idx" btree (name)
Check constraints:
  "people_geom_point_chk" CHECK (st_geometrytype(the_geom) =
                       'ST_Point'::text OR the_geom IS NULL)
Foreign-key constraints:
  "people_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id)
  "people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

16.5.5. Analizați Schema Noastră

Acum, schrma noastră ar trebui să arate în felul următor:

../../../_images/final_schema.png

16.5.6. Try Yourself hard

Creați marginile orașelor prin calucularea înfășurătorii convexe pentru toate adresele din acel oraș și calcularea unei zone tampon în jurul acesteia.

16.5.7. Accesul la Sub-Obiecte

Folosind funcțiile SFS-Model, aveți la dispoziție o largă gamă de opțiuni pentru accesarea sub-obiectelor geometriilor SFS. Când doriți să selectați primul punct vertex al fiecărei geometrii poligon în tabelul myPolygonTable, trebuie să o faceți în felul acesta:

  • Transform the polygon boundary to a linestring:

    select st_boundary(geometry) from myPolygonTable;
    
  • Select the first vertex point of the resultant linestring:

    select st_startpoint(myGeometry)
    from (
        select st_boundary(geometry) as myGeometry
        from myPolygonTable) as foo;
    

16.5.8. Procesarea Datelor

PostGIS suportă toate funcțiile conforme standardelor OGC SFS/MM. Toate aceste funcții încep cu ST_.

16.5.9. Decuparea

To clip a subpart of your data you can use the ST_INTERSECT() function. To avoid empty geometries, use:

where not st_isempty(st_intersection(a.the_geom, b.the_geom))
../../../_images/qgis_001.png
select st_intersection(a.the_geom, b.the_geom), b.*
from clip as a, road_lines as b
where not st_isempty(st_intersection(st_setsrid(a.the_geom,32734),
  b.the_geom));
../../../_images/qgis_002.png

16.5.10. Construirea de Geometrii pornind de la Alte Geometrii

Plecând de la de la un tabel de puncte dat, doriți să generați un linestring. Ordinea punctelor este dată de valoarea id. O altă metodă de ordonare ar putea fi marca de timp, cum ar fi cea pe care o primiți când capturiați puncte cu un receptor GPS.

../../../_images/qgis_006.png

To create a linestring from a new point layer called «points», you can run the following command:

select ST_LineFromMultiPoint(st_collect(the_geom)), 1 as id
from (
  select the_geom
  from points
  order by id
) as foo;

Pentru a vedea cum funcționează fără a crea un nou strat, puteți executa această comandă în stratul «people», deși desigur nu ar avea prea mult sens în lumea reală.

../../../_images/qgis_007.png

16.5.11. Curățarea Geometriilor

You can get more information for this topic in this blog entry.

16.5.12. Diferențele dintre tabele

To detect the difference between two tables with the same structure, you can use the PostgreSQL keyword EXCEPT:

select * from table_a
except
select * from table_b;

Ca rezultat, veți obține toate acele înregistrări din table_a care nu se regăsesc și în table_b.

16.5.13. Spațiile tabelelor

You can define where postgres should store its data on disk by creating tablespaces:

CREATE TABLESPACE homespace LOCATION '/home/pg';

Atunci când creați o bază de date, aveți posibilitatea să specificați care spațiu de tabelă să fie utilizat, de exemplu:

createdb --tablespace=homespace t4a

16.5.14. In Conclusion

Ați învățat cum să creeați geometrii mai complexe folosing instrucțiuni PostGIS. Rețineți că aceasta folosește la îmbunătățirea cunoștințelor pentru lucrul cu o bază de date spațială printr-o interfață GIS. În mod curent nu veți avea nevoie să folosiți aceste instrucțiuni manual, dar o înțelegere generală vă va ajuta la utilizarea unui GIS, în special dacă întâlniți erori care ar putea să pară altfel criptice.