NASA World Wind SDK
Bevezetés
A NASA World Wind SDK egy ingyenes API virtuális glóbuszokhoz. Segítségével könnyen vizualizálható interaktív háromdimenziós glóbusz vagy bármilyen földrajzi információ.
http://people.inf.elte.hu/hagtabi/foldgomb
Koncepció
A Web World Wind egy komponens amely beágyazódik a weboldalba. Ezt a komponenst hívjuk World Windownak.
World Window
A World Window objektum a funkcionalitást egy HTML canvas köré építi. A canvas általában egy "div" és az attribútumként megadott id-val paraméterezzük a World Window objektumot. Egy oldal több World Widow objektumot tartalmazhat, mindegyik canvashoz tartozik egy.
A World Window tartalmaz egy Globe-ot, egy Navigator-t és egy Layer List-et. Ezek automtiusan jönnek létre amikor a World Window konstruálódik. A Globe és Navigator lecserélhető. Ezeken felül a World Window felel még az eseménykezelésért.
Az World Window felépítése:
<div style="position:relative">
<canvas id="canvasOne" width="1000" height="1000" style="width: 100%; height: auto">
</canvas>
</div>
Rétegek
A World Wind mellett a rétegek a legfontosabb objektumok. Ezen rétegek tárolják a World Winden megjelenő összes információt. A képek, alakzatok, dekorációs elemek stb. mind-mind különálló rétegekben tárolódnak.
Minden World Wind objektum tartalmaz egy listát amely a rétegeket tartalmazza. Ezt nevezik Layer List-nek. Ez a lista tartalmazza az összes definiált réteget, és alapesetben üres. Amikor a World Wind rajzol, akkor bejárja ezt a listát és sorrendben megrajzolja a benne lévő rétegeket.
Fontosabb réteg attribútumok:
- displayName : Szöveg, a réteg nevét adhatjuk meg, és később ez megjeleníthető.
- enabled : Logikai, lehetővé teszi, hogy a réteget kikapcsoljuk, de közben a listában benne marad.
- pickEnabled : Logikai, megmondja, hogy a réteg és a tartalma "pickelhető-e".
- opacity : 0-1 közötti szám a réteg átlátszóságát szabályozza.
Két fontosabb rétegtípus van.
- Kép réteg: olyan képet tartalmaz amelyet a felszínre vetítünk ki. Ez tipikusan az egész földgömbre kiterjed de ez nem kötelező.
- Renderelhető réteg: akkor használjuk ha alakzatokat szeretnénk megjeleníteni.
// Létrehozzuk a World Window-t
var wwd = new WorldWind.WorldWindow("canvasOne");
// Létrehozzuk és hozzáadjuk a layereket
wwd.addLayer(new WorldWind.BMNGLayer());
wwd.addLayer(new WorldWind.BingAerialWithLabelsLayer(null));
wwd.addLayer(new WorldWind.CompassLayer());
wwd.addLayer(new WorldWind.CoordinatesDisplayLayer(wwd));
wwd.addLayer(new WorldWind.ViewControlsLayer(wwd));
Alakzatok
Alakzatok reprezentálják azokat az információkat amit meg szeretnénk jeleníteni és a földgömbhöz kapcsolódik. Egy ilyen objektum sokféle lehet, az egyszerű helyzet-jelölőtől kezdve a komplex rajzolt alakzatokig. Minden alakzat egy rétegben tárolódik és ez a réteg pedig megtalálható a World Wind Layer List-jében. Részletesen később.
Glóbusz
Globe reprezentál egy WGS84 elipszoidot és a területet. továbbá kezeli a különböző 2D-s projekciókat, ami használhatóak a +D-s glóbusz helyett. Alapesetben ezen kívül az alkalmazás nem nagyon lép interakcióba a glóbusszal. Ez alól kivétel például ha az alkalmazásunk a terület emelkedésével szeretne számolni.
Minden World Window-nak eg Globe-ja van és automatikusan létrejön, amikor a World Window is. Az alkalmazásban a Globe lecserélhető egy másikra.
A Navigator objektum felelős azért, hogy a felhasználói interakciókat átalakítsa a földgömbön megjelenő változásokká. Folyamatosan figyeli az egér eseményeket és ezeket alakítja át mozgássá, forgatássá vagy zoomolássá. A Navigator segítségével lehet egy adott pozícióra navigálni.
Minden World Wind objektumnak megvan a saját Navigator objektuma, Ez a Navigator automatikusan jön létre, akkor amikor a World Wind objektumok létrejön. Ez a Navigator lecserélhető, ha a fejlesztő készített egy másképp működőt amely jobban megfelel az igényeknek.
Főbb funkcionalitások
Alakzatok
Szövegek
Egy adott földrajzi ponthoz tartozó szöveget reprezentál.
// Példa adat
var peaks =
[
{
'name': "Mount McKinley\n(Denali)", // Mount McKinley
'state': "Alaska",
'elevation': 6194,
'latitude': 63.0690,
'longitude': -151.0063
}];
var text,
textAttributes = new WorldWind.TextAttributes(null),
textLayer = new WorldWind.RenderableLayer("U.S.A. Peaks");
//Alap attribútumok beállítása (pl: szín)
textAttributes.color = WorldWind.Color.CYAN;
textAttributes.depthTest = false;
//Létrehozzuk a szöveg "alakzatokat"
for (var i = 0, len = peaks.length; i < len; i++) {
var peak = peaks[i],
peakPosition = new WorldWind.Position(peak.latitude, peak.longitude, peak.elevation);
text = new WorldWind.GeographicText(peakPosition, peak.name + "\n" + peak.state);
//Beállítjuk az alakzatohoz a szöveget
text.attributes = textAttributes;
//Hozzáadjuk a szöveget a layerhez
textLayer.addRenderable(text);
}
//A szöveg layert hozzáadjuk a globál layerhez
wwd.addLayer(textLayer);
//Létrehozunk egy managert, hogy tudjuk vezérelni a szöveg réteget.
var layerManger = new LayerManager(wwd);
Utak
Egyenes vagy görbe vonalat reprezentál előre megadott pozíciók között. A megrajzolt vonal az alábbi típusú lehet:
- WorldWind.GREAT_CIRCLE
- WorldWind.RHUMB_LINE
- WorldWind.LINEAR
Az utat alkotó pontok közötti magasságot meghatározza az út magasság módja amely az alábbiak lehetnek:
- WorldWind.ABSOLUTE
- WorldWind.RELATIVE_TO_GROUND
- WorldWind.CLAMP_TO_GROUND
Külön attribútumok tartoznak a normál és a kiemelt megjelenítéshez.
// Úthoz tartozó poziciók létrehozása
var pathPositions = [];
pathPositions.push(new WorldWind.Position(40, -100, 1e4));
pathPositions.push(new WorldWind.Position(45, -110, 1e4));
pathPositions.push(new WorldWind.Position(46, -122, 1e4));
// Az út létrehozása
var path = new WorldWind.Path(pathPositions, null);
path.altitudeMode = WorldWind.RELATIVE_TO_GROUND;
path.followTerrain = true;
path.extrude = true;
path.useSurfaceShapeFor2D = true;
// Az úthoz tartozó attribútumok étrehozása
var pathAttributes = new WorldWind.ShapeAttributes(null);
pathAttributes.outlineColor = WorldWind.Color.BLUE;
pathAttributes.interiorColor = new WorldWind.Color(0, 1, 1, 0.5);
pathAttributes.drawVerticals = path.extrude;
path.attributes = pathAttributes;
// Kiemelés létrehozása
var highlightAttributes = new WorldWind.ShapeAttributes(pathAttributes);
highlightAttributes.outlineColor = WorldWind.Color.RED;
highlightAttributes.interiorColor = new WorldWind.Color(1, 1, 1, 0.5);
path.highlightAttributes = highlightAttributes;
//Az utat hozzáadjuk egy layerhez, és betesszük a globális layerbe
var pathsLayer = new WorldWind.RenderableLayer();
pathsLayer.displayName = "Paths";
pathsLayer.addRenderable(path);
wwd.addLayer(pathsLayer);
//Layermanager létrehozása
var layerManger = new LayerManager(wwd);
//Eseménykezelés a kiemeléshez
var highlightController = new WorldWind.HighlightController(wwd);
Poligonok
Egy 3D-s poligont reprezentál. A poligonnak több határt is beállíthatunk, ezzel üres területeteket képezve. A poligon magassága az alábbiak lehetnek:
- WorldWind.WorldWind.ABSOLUTE
- WorldWind.RELATIVE_TO_GROUND
- WorldWind.CLAMP_TO_GROUND
Külön attribútumok tartoznak a normál és a kiemelt megjelenítéshez.
//Létrehozzuk a poligonokat tároló réteget
var polygonsLayer = new WorldWind.RenderableLayer();
polygonsLayer.displayName = "Polygons";
wwd.addLayer(polygonsLayer);
//Létrehozzuk a poligon határait
var boundaries = [];
boundaries[0] = []; // külső határ
boundaries[0].push(new WorldWind.Position(40, -100, 1e5));
boundaries[0].push(new WorldWind.Position(45, -110, 1e5));
boundaries[0].push(new WorldWind.Position(40, -120, 1e5));
boundaries[1] = []; // belső határ
boundaries[1].push(new WorldWind.Position(41, -103, 1e5));
boundaries[1].push(new WorldWind.Position(44, -110, 1e5));
boundaries[1].push(new WorldWind.Position(41, -117, 1e5));
//Létrehozzuka a poligont és hozzáadjuk az attribútumait.
var polygon = new WorldWind.Polygon(boundaries, null);
polygon.altitudeMode = WorldWind.ABSOLUTE;
polygon.extrude = true;
var polygonAttributes = new WorldWind.ShapeAttributes(null);
polygonAttributes.drawInterior = true;
polygonAttributes.drawOutline = true;
polygonAttributes.outlineColor = WorldWind.Color.BLUE;
polygonAttributes.interiorColor = new WorldWind.Color(0, 1, 1, 0.5);
polygonAttributes.drawVerticals = polygon.extrude;
polygonAttributes.applyLighting = true;
polygon.attributes = polygonAttributes;
//Létrehozzuk a poligonhoz tartozó kiemelést
var highlightAttributes = new WorldWind.ShapeAttributes(polygonAttributes);
highlightAttributes.outlineColor = WorldWind.Color.RED;
highlightAttributes.interiorColor = new WorldWind.Color(1, 1, 1, 0.5);
polygon.highlightAttributes = highlightAttributes;
//Hozzáadjuk a layerhez
polygonsLayer.addRenderable(polygon);
Helyjelző
Bármilyen pozíción megjelenő képet/címkét reprezentál. Lehet használni a beépített képeket vagy használhatunk sajátot, illetve a html-el is lehet rajzolni.
// Definiáljuk a képeket amiket helyjelzőnek használunk.
var images = [
"plain-black.png",
"plain-blue.png"
];
var pinLibrary = WorldWind.configuration.baseUrl + "images/pushpins/", // a képek helye
placemark,
placemarkAttributes = new WorldWind.PlacemarkAttributes(null),
highlightAttributes,
placemarkLayer = new WorldWind.RenderableLayer("Placemarks"),
latitude = 47.684444,
longitude = -121.129722;
// Létrehozzuk a közös attribútumokat.
placemarkAttributes.imageScale = 1;
placemarkAttributes.imageOffset = new WorldWind.Offset(
WorldWind.OFFSET_FRACTION, 0.3,
WorldWind.OFFSET_FRACTION, 0.0);
placemarkAttributes.imageColor = WorldWind.Color.WHITE;
placemarkAttributes.labelAttributes.offset = new WorldWind.Offset(
WorldWind.OFFSET_FRACTION, 0.5,
WorldWind.OFFSET_FRACTION, 1.0);
placemarkAttributes.labelAttributes.color = WorldWind.Color.YELLOW;
placemarkAttributes.drawLeaderLine = true;
placemarkAttributes.leaderLineAttributes.outlineColor = WorldWind.Color.RED;
// Minden képhez létrehozunk egy Placemarkot és címkét
for (var i = 0, len = images.length; i < len; i++) {
placemark = new WorldWind.Placemark(new WorldWind.Position(latitude, longitude + i, 1e2), true, null);
placemark.label = "Placemark " + i.toString() + "\n"
+ "Lat " + placemark.position.latitude.toPrecision(4).toString() + "\n"
+ "Lon " + placemark.position.longitude.toPrecision(5).toString();
placemark.altitudeMode = WorldWind.RELATIVE_TO_GROUND;
.
placemarkAttributes = new WorldWind.PlacemarkAttributes(placemarkAttributes);
placemarkAttributes.imageSource = pinLibrary + images[i];
placemark.attributes = placemarkAttributes;
//Létrehozzuk a kiemeléshez tartozó attribútumokat
highlightAttributes = new WorldWind.PlacemarkAttributes(placemarkAttributes);
highlightAttributes.imageScale = 1.2;
placemark.highlightAttributes = highlightAttributes;
//Hozzáadjuk a réteghez.
placemarkLayer.addRenderable(placemark);
}
// Hozzáadjuk a réteget a globális réteghez.
wwd.addLayer(placemarkLayer);
// Létrehozunk egy Layermanagert a kezelhetőségért
var layerManger = new LayerManager(wwd);
További alakzatok
- Felszíni alakzatok: Hasonlóak a fent taglalt Poligonokhoz. (Surface Shapes)
- Képernyő kép: Segítségével képernyő-re képet rajzolhatunk. (Screen Image)
- Képernyő szöveg : Segítségével szöveget helyezhetünk el a képernyőn. (Screen Text)