DOMBORZAT MODELL, TEREPMETSZET KÉSZÍTÉS (INTERPOLÁCIÓ) Terepfelmérés során többnyire szórt pontokban kapunk magassági értékeket, melyekből szeretnénk digitális domborzatmodellt készíteni, szintvonalas ábrát vagy metszeteket rajzolni az éppen aktuális feladatnak megfelelően. A digitális domborzatmodell készítése során a szórt pontokban történő felmérés eredményéből szeretnénk egy olyan modellt előállítani, amiből a felmért terület bármely pontjában kiszámolható a magasság értéke. Ez történhet például Delaunay háromszögeléssel és utána lineáris interpolációval, vagy akár spline interpolációval is. A domborzatmodellt többnyire rácshálóra interpolált értékekkel adjuk meg. A már elkészült domborzatmodellből levezethetünk szintvonalas térképeket vagy terepmetszeteket is. A terepfelmérés során mért koordinátáink a meres_coo.txt fájlban találhatóak a következő formátumban (pontszám, EOV koordináták (Y,X), Balti tengerszint feletti magasság): 2001 577057.011 188795.517 142.042 2002 577051.903 188783.028 140.821 2003 577051.044 188772.868 140.317 2004 577053.460 188758.714 139.622 2005 577053.097 188757.082 139.478 2006 577052.829 188752.585 139.186 2007 577043.018 188773.355 139.426 Miután azonos típusú, sorhosszúságú adataink vannak a beolvasás egyszerűen megtörténhet a load-dal. clear all; close all; clc; page_screen_output(0); % ez csak Octave-ban kell! data=load('meres_coo.txt'); x = data(:,2); y = data(:,3); z = data(:,4); LINEÁRIS INTERPOLÁCIÓ (RÁCSRA) Interpoláljuk méterszer méteres rácshálóra a mért értékeket a griddata parancs használatával! Ehhez először egy megfelelő rácshálót kell generálnunk a meshgrid használatával. % Interpoláció rácshálóra meshgrid és griddata használatával [XI YI] = meshgrid(floor(min(x)):ceil(max(x)), floor(min(y)):ceil(max(y))); ZI = griddata(x, y, z, XI, YI); % Matlabban: 'linear'-(default), 'cubic', 'nearest', 'v4' method % Octave-ban: 'linear'-(default), 'nearest' method 1
Az alapértelmezett a lineáris interpoláció. Ez Delaunay háromszögelést használ, és a háromszögekre síkot illesztve számolja ki minden pont magasságát. Jelenítsük meg a háromszögeket! figure(1) tri = delaunay(x, y); triplot(tri, x, y); title('delaunay haromszogek'); % Szintvonalak rajzolása a griddata % eredményének felhasználásával figure(2) a = ceil(min(z)) b = floor(max(z)) [C, h] = contour(xi, YI, ZI, a:b); %clabel(c, h, a:b); clabel2(c, a:b); title('linearis interpolacio'); Megjegyzés: a szintvonalak feliratozására a clabel parancsot is használhatjuk. Octave-ban azonban célszerű ennek egy módosított változatát használni, mivel az eredeti bizonyos esetekben túl sűrűn feliratozza a szintvonalakat. Vegyük észre, hogy extrapoláció nem történt az egész rácsra, csak a mért pontjainkat befoglaló konvex sokszögön belül vannak értékeink. (Ellenőrizzük le a ZI interpolált értékeket! Ahol nem volt adat oda NaN (not a number) értékek kerültek.) 2
SPLINE INTERPOLÁCIÓ (RÁCSRA) A köbös spline interpoláció Matlabban megoldható a griddata egy másik beépített módszerével, a cubic használatával, ezt azonban Octave alá még nem implementálták. Helyette telepítsük a spline módult és használjuk csomag tpaps parancsát (thin plate spline). % spline csomag telepítése internetről közvetlenül: % pkg install -forge splines pkg load splines; ZI2 = tpaps([x y], z, 1, [XI(:) YI(:)]); % Ugyanezzel a módszerrel Matlabban: % st = tpaps([x y]', z', 1); % ZI2 = fnval(st, [XI(:) YI(:)]'); ZI2 = reshape(zi2, size(xi)); ZI2(isnan(ZI)) = nan; % az extrapoláció kiküszöbölése A tpaps parancs ellentétben a griddata-val nem a meshgrid által mátrix formában előállított rácshálóban kéri az interpolálandó pontok helyét, hanem vektorosan összetartozó [xi yi] értékpárokat kér. Ezáltal azonban nem csak rácshálóra végezhető interpoláció, hanem bármilyen pontokra! A bemenetnél is összetartozó [x y] értékpárokra van szükség egy mátrixban, és a hozzájuk tartozó z értékekre egy külön vektorban. Utána megadható egy 0-1 közötti szám, ami a simítási tényező, ami a vékony lemez merevségét jellemzi. 0 esetén teljesen merev, ekkor egy közelítő síkot illeszt a pontokra, 1 esetén pedig interpolál, azaz minden ponton átmegy a felület. A kettő között valamilyen regresszió van, minél közelebb van a szám 0-hoz, annál inkább a síkhoz hasonló sima felületet kapunk. Octave-ban egy paranccsal hívható a módszer, Matlab esetén két parancs kell, először kiszámítjuk a spline együtthatóit, és utána az fnval paranccsal kiértékeljük az eredményt a rácspontokban. A vektoros formában történő megadáshoz a meshgrid eredményeképpen kapott XI, YI értékekeket oszlopvetorrá alakítottuk az XI(:) és YI(:) parancsokkal. Az eredményt a szintvonalas megjelenítéshez visszaalakítjuk mátrix alakba (reshape). Mivel ezzel a módszerrel extrapolálni is lehet, ahol viszont nagyon rossz eredményeink lennének, ezért az extrapolált helyeket NAN-nel töltjük fel. Ehhez felhasználtuk a lineáris interpoláció eredményét. % A spline interpoláció szintvonalas megjelenítése figure(3) [C, h] = contour(xi, YI, ZI2, a:b); clabel2(c, a:b); title('spline interpolacio'); 3
Ez a módszer jóval simább szintvonalakat eredményez, mint a lineáris interpoláció. EGYÉB MEGJELENÍTÉSI MÓDOK Szintvonalas megjelenítésen kívül magasság szerinti színátmenetes megjelenítéssel is ábrázolhatjuk a dolmborzatmodellünket. Ehhez használhatjuk az imagesc parancsot. Ez tulajdonképpen egy mátrixot jelenít meg képként. Matlabban a bemenő x és y koordináták vektorban adottak, míg a z koordináták egy rácsháló pontjaiban. Octave-ban a bemenő x és y koordináták is maradhatnak a meshgrid által előállított mátrixos formában. Matlabban ki kell vegyünk a mátrixból egy sort és oszlopot. Az imagesc koordináta rendszere a képek koordináta rendszerének felel meg (ij), azaz a bal felső sarok a kezdőpont, szemben a nálunk használt észak-keleti (xy) tájolású koordináta rendszerekkel. A kettő között az axis xy vagy axis ij paranccsal lehet váltani. A színskálát kitenni a colorbar paranccsal tudjuk, a színskálát változtatni pedig a colormap paranccsal. Próbáljunk ki különböző színskálákat! Alapértelmezett a jet skála. Egyéb: hot, hsv, summer, autumn, spring, winter, cool, grey, lines... % A lineáris interpoláció domborzatszínezéses megjelenítése figure(4); imagesc(xi(1,:), YI(:,1), ZI); % Octave alatt meshgriddel előállított raszterral is működik % imagesc(xi, YI, ZI); axis xy; colorbar; title('linearis interpolacio'); % Probaljunk ki kulonbozo szinskalakat! - colormap - alapértelmezett: jet % hot, hsv, summer, autumn, spring, winter, cool, grey, lines... colormap(hsv) 4
Másik ábrázolási lehetőség a 3D-ben színezett felülettel történő megjelenítés, a surf paranccsal. % A lineáris interpoláció megjelenítése felületként figure(5); surf(xi,yi,zi,'edgealpha',0) Itt az EdgeAlpha paraméter 0-ra állítása azért szükséges, hogy a zavaró felülethatárok ne rajzolódjanak ki. 5
ELTÉRÉS A KÉTFÉLE INTERPOLÁCIÓ KÖZÖTT Számoljuk ki a kétféle interpoláció között az eltéréseket, majd tegyük fel a színezett rajzra a ténylegesen mért pontokat! % Elteres a ketfele interpolacio kozott DZ = ZI - ZI2; figure(6); imagesc(xi(1,:), YI(:,1), DZ); axis xy; colorbar; plot(x, y, 'k+'); title('elteres'); A maximális eltérés helye: DZmax = max(max(abs(dz))); % maximalis elteres [imax jmax] = find(abs(dz) == DZmax); % a max. elteres helye plot(xi(imax,jmax), YI(imax,jmax), 'yd'); Az eltérés ott a legnagyobb, ahol nincsenek mért pontjaink. Ezeken a helyeken a lineáris interpoláció egyszerűen levágja az értékeket egy egyenessel, a spline pedig a korábbi görbületekkel folytatva számítja a felületet. Ezt a legkönnyebben metszetek felvételével nézhetjük meg. 6
TEREPMETSZETEK KIRAJZOLÁSA Készítsünk Észak-Dél és Kelet-Nyugat irányú metszeteket egy tetszőleges pontban! Ehhez először ki kell választanunk egy pontot valamelyik felülnézeti rajzon. Válasszuk ki most a 4-es ábrát, amin a domborzatszínezéses megjelenítés volt és a ginput paranccsal adjunk meg rajta egy pontot! % Terepmetszetek készítése tetszőleges pontban figure(4); [xa ya] = ginput(1); plot(xa, ya, 'k*'); A Kelet-Nyugat és Észak-Dél irányú metszetekhez ahhoz a sorhoz iletve oszlophoz tartozó Z értékeket kell kirajzoltatni, ami megfelel az xa-ban illetve ya-ban tárolt értékeknek. % Nyugat-Kelet iranyu metszet tetszoleges helyen i = find(yi(:,1)==round(ya)) figure(7); plot(xi(i,:), ZI(i,:), 'r'); plot(xi(i,:), ZI2(i,:), 'b') legend('linearis', 'Spline'); title('nyugat-kelet iranyu metszet'); % Eszak-Del iranyu metszet tetszoleges helyen j = find(xi(1,:)==round(xa)) figure(8); plot(yi(:,j), ZI(:,j), 'r'); plot(yi(:,j), ZI2(:,j), 'b'); legend('linearis', 'Spline'); title('del-eszak iranyu metszet'); A tetszőleges metszet felvételéhez két pontot kell kiválasztani a ginput paranccsal! % Metszet tetszőleges irányban figure(4); [xa ya] = ginput(1); plot(xa, ya, 'r*'); [xb yb] = ginput(1); plot(xb, yb, 'r*'); plot([xa xb], [ya yb], 'r'); 7
Ezután a két végpont között felveszünk 100 pontot, és ezekben kiszámoljuk interpolációval a z értékeket, akár a lineáris, akár a spline interpoláció eredményét felhasználva az interp2 paranccsal. Ez pont a fordítottja a korábbi szórt pontokról rácsra történő interpolációnak, itt a rácsháló pontjait használjuk fel, hogy tetszőleges pontokban magasságot számoljunk. xm = linspace(xa, xb, 100); ym = linspace(ya, yb, 100); zm = interp2(xi, YI, ZI, xm, ym); zm2 = interp2(xi, YI, ZI2, xm, ym); A z értékeket a kezdőponttól mért távolság függvényében fogjuk megjeleníteni. Ehhez ki kell számolnunk a távolságokat! s = sqrt((xm-xa).^2 + (ym-ya).^2); figure(9); plot(s, zm, 'r'); plot(s, zm2, 'b'); legend('linearis', 'Spline'); title('altalanos iranyu metszet'); A metszeteket hasonló módon kirajzoltathatjuk a maximális eltérés helyén is. % Nyugat-Kelet irányú metszet a maximális eltérés helyén figure(10) plot(xi(imax,:), ZI(imax,:), 'r'); plot(xi(imax,:), ZI2(imax,:), 'b'); plot(xi(imax,jmax), ZI(imax,jmax), 'g*'); plot(xi(imax,jmax), ZI2(imax,jmax), 'g*'); legend('linearis interpolacio', 'Spline interpolacio', 'Maximalis elteres helye'); title('ny-k iranyu metszet a maximalis elteres helyen'); % Eszak-Del irányú metszet a maximális eltérés helyén figure(11); plot(yi(:,jmax), ZI(:,jmax), 'r'); plot(yi(:,jmax), ZI2(:,jmax), 'b'); plot(yi(imax,jmax), ZI(imax,jmax), 'g*'); 8
plot(yi(imax,jmax), ZI2(imax,jmax), 'g*'); legend('linearis interpolacio', 'Spline interpolacio', 'Maximalis elteres helye'); title('d-e iranyu metszet a maximalis elteres helyen'); TEREPRENDEZÉS UTÁNI FELÜLETTEL TÖRTÉNŐ ÖSSZEHASONLÍTÁS, FÖLDTÉRFOGATOK SZÁMÍTÁSA A területen elegyengetták a kisebb nagyobb egyenetlenségeket, ezután készült egy újabb felmérés a területről. számoljuk ki ezek alapján a szükséges földmunka mennyiségét! Először töltsük be a simított állományt! simitas = load('simitas_coo.txt'); xs = simitas(:,2); ys = simitas(:,3); zs = simitas(:,4); Interpoláljunk lineárisan rácshálóra, majd nézzük meg a különbséget a korábbi felületeinkkel! ZI3 = griddata(xs, ys, zs, XI, YI); foldmunka = ZI3 - ZI; foldmunka2 = ZI3 - ZI2; Ábrázoljuk a simított felületet szintvonalakkal! figure(12); hold off; [C, h] = contour(xi, YI, ZI3, a:b); clabel2(c, a:b); %plot(xs, ys, 'k+'); title('rendezes utan'); Ábrázoljuk a földmunka mennyiségét! figure(13); imagesc(xi(1,:), YI(:,1), foldmunka); axis xy; colorbar; title('foldmunka'); Számoljuk ki a szükséges töltés/bevágás mennyiségét! Mivel a rácsháló méterszer méteres így könnyű dolgunk van, csak összegezni kell a pixelek számát. toltes = sum(foldmunka(foldmunka > 0)) bevagas = sum(foldmunka(foldmunka < 0)) egyenleg = toltes+bevagas toltes2 = sum(foldmunka2(foldmunka2 > 0)) bevagas2 = sum(foldmunka2(foldmunka2 < 0)) egyenleg2 = toltes2+bevagas2 9