Go to content Go to navigation Go to search

geo-spatial.org: An elegant place for sharing geoKnowledge & geoData

Căutare



RSS / Atom / WMS / WFS


Contact


Lista de discuții / Forum


Publicat cu Textpattern


Comunitatea:

Conferința FOSS4G 2019
Conferința FOSS4G 2018

Conversia fișierelor SHP în format KML folosind GDAL/OGR

de Vasile Crăciunescu

Publicat la 12 Jul 2010 | Secţiunea: Tutoriale | Categoria: GIS/
Nivel de dificultate:

Introducere

Am scris acest tutorial urmare a unei întrebări sosite pe lista de discuții. Pe scurt, în mesajul respectiv se cere găsirea unei soluții pentru transformarea în mod batch a fiecărei entități poligonale dintr-un fișier de tip ESRI Shapefile în fișiere individuale de tip Google Earth (KML/KMZ). Tutorialul răspunde atît problemei ridicate cît și celei mai generale, de conversie SHP2KML. Pe piață există mai multe soluții software care pot face aceste operațiuni. Pentru acest tutorial m-am oprit la instrumente open sorce, precum suita GDAL/OGR, QGIS, OpenOffice.

SHP2KML

Comanda ogr2ogr permite efectuare de conversii pentru un număr impresionant de formate de stocare a datelor geospațiale vectoriale. Pentru instalarea GDAL/OGR vă invit să consultați materialul Realizarea unui super mozaic raster folosind instrumente open source. Ilustrarea pașilor necesari pentru conversie o vom face utilizînd stratul Județe România, disponibil pentru download pe geo-spatial.org.

Pentru început vă propun să studiem forma comenzii care ne permite conversia SHP2KML. Pentru aceasta vom deschide o fereastră în linie de comandă, vom naviga în folderul în care am dezarhivat fișierul cu limitele de județ și vom scrie următoarea comandă:

		ogr2ogr -f KML -s_srs "EPSG:31700" -t_srs "EPSG:4326" judete_ro.kml judete_ro.shp
	

Explicația parametrilor din linia de comandă este dată mai jos:

  • -f KML specifică formatul de fișier în care va fi stocat rezultatul prelucrării, în cazul nostru KML;
  • -s_srs “EPSG:31700” specifică sistemul de coordonate al datelor de intrare (source spatial reference set), în cazul nostru Stereo70, reprezentat prin codul EPSG 31700;
  • -t_srs “EPSG:4326” specifică sistemul de coordonate pentru fișierul rezultat din prelucrare (target spatial reference set). Formatul KML impune utilizarea sistemului EPSG:4326
  • judete_ro.kml numele fișierului de ieșire (fișierul în care va fi stocat rezultatul transformării);
  • judete_ro.shp numele fișierului de intrare.

Dacă totul a funcționat corect, rezultatul în Google Earth ar trebui să fie similar cu cel din Figura 1 (limitele de județe sînt reprezentate cu roșu).

Figura 1. Rezultatul conversiei în format KML.

Dacă veți da click pe oricare din județe veți observa că atributele din tabela .dbf au fost și ele convertite în format KML. GDAL/OGR permite și indicarea unui cîmp ale cărui valori să fie afișate în Google Earth (sau alt geobrowser compatibil KML) sub formă de etichete. Din păcate, această opțiune funcționează doar în cazul entităților de tip punct. Dacă dorim să avem etichete afișate pentru un strat de tip poliogon putem apela la un mic truc, grupînd într-un KML un strat de tip poligon cu unul din care am extras centroizii poligoanelor și le-am exportat de asemenea în format KML. Pentru a ilustra acest lucru am obținut, în QGIS + extensia fTools, centroizii poligoanelor din stratul “judete_ro” folosind funcția Vector/Geometry Tools/Polygon Centroids (Figura 2).

Figura 2. Extragerea centroizilor din stratul de tip poligon.

Stratul de tip punct obținut a fost exportat în format KML folosind urmăroarea comandă:

		ogr2ogr -f KML -s_srs "EPSG:31700" -t_srs "EPSG:4326" judete_ro_point.kml judete_ro_point.shp -dsco NameField=DENJUD
	

Remarcați opțiunea -dsco NameField=DENJUD care permite stabilirea cîmpului ce va fi folosit pe post de etichetă. Încărcînd ambele fișiere KML în Google Earth obținem un rezultat similar cu cel prezentat în Figura 3. Informațiile din tabela de atribute pot fi de asemenea vizualizate dînd click mouse stînga pe centroidul județului de interes.

Figura 3. Încărcarea fișierelor de tip poligon și punct în Google Earth.

Alți parametri care pot fi controlați la export cu ajutorul GDAL/OGR sînt:

  • DescriptionField permite preluarea dintr-un cîmp a textului “Description” ce apare în dreptul fiecărui element din lista de straturi în Google Earth.
  • AltitudeMode aplicabil doar pentru elementele cu geometrie 3D. Permite stabilirea modului în care valorile de altitudine atașate unui element vor fi interpretate la afișarea în Google Earth (clampToGround ignoră valorile de altitudine și plasează obiectul la nivelul terenului, relativeToGround plasează elementul la altitudinea terenului + valoare de altitudine asociată elementului, absolute plasează elementul la altitudinea indicată de geometrie).

Un exemplu de utilizare a acestor doi parametri este prezentat în continuare:

		ogr2ogr -f KML -s_srs "EPSG:31700" -t_srs "EPSG:4326" judete_ro_point.kml judete_ro_point.shp -dsco NameField=DENJUD -dsco DescriptionField=SIRUTA -dsco AltitudeMode=absolute
	

SHP2KML batch mode

Bun, am reușit să convertim fișierul SHP în KML dar nu am rezolvat și problema ridicată pe lista de discuții. Pentru aceasta e nevoie să obținem 42 de fișiere de tip KML, fiecare conținînd limitele unui singur județ. ogr2ogr permite acest lucru folosind interogări de tip SQL. De exemplu, comanda pentru crearea unui KML cu limitele județului Suceava (Figura 4) va avea următoarea formă:

		ogr2ogr -f KML -s_srs "EPSG:31700" -t_srs "EPSG:4326" suceava.kml judete_ro.shp -sql "SELECT * FROM judete_ro WHERE DENJUD = SUCEAVA"
	

Figura 4. Exemplu export KML pentru județul Suceava.

Problema e rezolvată dacă vom repeta această comandă de 42 de ori, schimbînd de fiecare dată numele județului. Ce ne facem însă dacă în loc de 42 de entități avem cîteva zeci sau sute de mii? Greu. Pentru aceasta va trebui să găsim o metodă care să ne permită rularea automată a comenzilor.

Soluția 1: o aplicație de calcul tabelar

Cei fără cunoștințe și talent la programare pot folosi funcționalitatea de autocompletare a valorilor în celule, disponibilă în toate programele de calul tabelar (Ex: OpenOffice Calc, Microsoft Excel), pentru a obține un fișier de tip .bat. La o privire atentă asupra comenzii vom observa că avem două locuri (le putem zice variabile) în care trebuie să schimbăm valoarea cu numele județului curent. Este vorba de numele fișierului KML și numele județului în secvența de interogare. Am ales să fac acest lucru folosind OpenOffice Calc, unde am deschis fișierul judete_ro.dbf. Observați că numele județului se găsește în coloana A. Pentru a construi semi-automat lista de comanzi vă invit să selectați celula K2, plasați cursorul în bara Input line și scrieți comanda:

		=CONCATENATE("ogr2ogr -f KML -s_srs 'EPSG:31700' -t_srs 'EPSG:4326' ";A2;" judete_ro.shp -sql 'select * from judete_ro where denjud = """;A2;"""'")
	

Selectați din nou celula K2, plasați cursorul în dreptul punctului negru din partea dreaptă-jos a celulei și trageți de acesta pînă ajungeți la linia 43. Daca totul a funcționat corect ar trebui să obțineți valori similare cu cele prezentate în Figura 5.

Figura 5. Crearea fișierului Windows Batch folosind OpenOffice Calc.

Copiați valorile din liniile 2-43 ale coloanei K în clipboard și transferați-le într-un editor de text. Salvați fișierul ca “conversie_shp2kml.bat” în același folder cu fișierul “judete_ro.shp”. Deschideți o fereastră în linie de comandă, navigați în folderul cu date și tastați comanda “conversie_shp2kml.bat”.

Soluția 2: programatic

GDAL/OGR este scris în C++. Cei ce cunosc acest limbaj de programare pot scrie, relativ ușor, un program care să includă biblioteca GDAL/OGR pentru a rezolva într-o buclă problema conversiei. De asemenea, pentru un număr de limbaje de programare există posibilitatea de a interacțiunea direct cu GDAL/OGR prin intermediul unor interfețe dedicate (Ex: Perl, Python, Ruby, Java, VB6, C#, .Net). Mai mult, orice limbaj de programare care suporta funcția exec poate fi folosit pentru a crea o buclă de execuție ogr2ogr. Deoarece eu unul mă simt bine în PHP voi prezenta un exemplu de utilizare folosind acest limbaj de programare:

<?php
//creeaza un array cu numele judetelor
//informatia poate fi citita dintr-un fisier sau o baza de date (varianta recomandat%u0103 cind se lucreaza cu un numar mare de elemente)
$judete = array('TELEORMAN', 'MUNICIPIUL BUCURESTI', 'GIURGIU', 'CALARASI', 'DOLJ', 'ILFOV', 'CONSTANTA', 'IALOMITA', 'OLT', 'MEHEDINTI', 'GORJ', 'DAMBOVITA', 'PRAHOVA', 'BRAILA', 'TULCEA', 'VALCEA', 'ARGES', 'CARAS-SEVERIN', 'BUZAU', 'BRASOV', 'GALATI', 'VRANCEA', 'TIMIS', 'SIBIU', 'COVASNA', 'HUNEDOARA', 'ALBA', 'ARAD', 'BACAU', 'VASLUI', 'MURES', 'HARGHITA', 'NEAMT', 'CLUJ', 'SALAJ', 'BISTRITA-NASAUD', 'IASI', 'BIHOR', 'SUCEAVA', 'MARAMURES', 'SATU MARE', 'BOTOSANI');
//se parcurge intr-o bucla lista de judete si se creeaza fisierele .kml
foreach ($judete as $judet)
{
	exec('ogr2ogr -f KML -s_srs "EPSG:31700" -t_srs "EPSG:4326" -sql "SELECT * FROM judete_ro WHERE DENJUD = \''.$judet.'\'" \''.strtolower($judet).'.kml\' judete_ro.shp');
}
?>
	

Notă
Deoarece în cîmpul DENJUD, folosit pentru crearea fișierelor individuale, există cîteva valori delimitate cu spațiu (Ex: Municipiul București) am fost nevoit să folosesc secvențe escape (caracterul “\”) pentru a include între ghilimele valorile pentru interogarea SQL. Același lucru a fost făcut și în exemplul din aplicația de calcul tabelar, folosind sintaxa corespunzătoare OpenOffice Calc. În mod normal, pentru astfel de operații se recomandă folosirea unui cîmp unic, de tip numeric numeric (în cazul datelor noastre cîmpul SIRUTA se preta foarte bine), unde nu ar fi existat necesitatea folosirii “/” și care ne garantează că nu vom avea două sau mai multe entități cu același nume. În exemplul de mai sus am mai folosit funcția strtolower() pentru a schimba numele județelor din “UPPERCASE” în “LOWERCASE”.

Simbolizare KML

GDAL/OGR execută conversia geometriei și atributelor dintr-un format de fișier în altul. Din păcate nu oferă decît suport minimalistic pentru partea de simbolizare. Aplicarea unor simbologii particularizate presupune transformarea fișierului KML obținut cu ogr2ogr folosind tehnologia XSLT. Despre aceste chestiuni vom vorbi în partea a doua a tutorialului care va fi publicată săptămîna viitoare. Pînă atunci vă așteptăm părerile pe lista de discuții.

Discută articolul (1 comentarii)

Categorii