View Source

{section}
{column:width=70%}

h2. Java API for KML - Advanced Example3
{toc:minLevel=3|maxLevel=5|type=flat}
h3. The concept
This series of more sophisticated JAK examples is trying to show the capabilities what is possible with KML in Java. They show the usage of JAK for generating some nice-looking KML files, which can be viewed with Google Earth.

{info:title=Important!}
JAK only works if all dependencies are resolved! That are mainly [JAK|http://code.google.com/p/javaapiforkml/] and [JAXB|https://jaxb.dev.java.net/]! For further instructions check out the [jak:FAQ].
{info}

h3. Mobile Phone Subscriptions 2008.

The third example integrates statistic data to the polygons. It reads data of mobile phone subscriptions in 2008 from a CSV and set the height of the polygons to the value of the data for each country. The data can be found on this site: [data.un.org|http://data.un.org] and is saved as CSV file. The 3D Polygons for the border of each country are created the same way as described in [jak:Advanced Example2].

!example3.png!
h6. Figure 1: Mobile Phone Subscriptions 2008 in Google Earth.


h3. The Code
In this example the CSV date file is parsed and the values are stored in a {{HashMap<String, Double>}} The country name is the key, while the value is the mobile phone subscriptions value. The program traverse through the countries of the world (saved as placemark objects) and obtained from the _World Borders Dataset_ and checks if mobile subscription data exist for the current country. The height and the color of the country are now set according to the mobile subscription value.

{code:title=Listing 1: Mobile Phone Subscriptions 2008 in Google Earth}
HashMap<String, Double> data = Utils.readCSVDoubleData("src/main/resources/exampledata/mobile_phone_2008.csv", 0, 3);
double max = data.get("maximum");
int minPolyHeight = 308000;
int maxPolyHeight = 2692000; // real max = 3000000 - 308000 = 2692000

Kml unmarshal = Kml.unmarshal(new File("src/main/resources/exampledata/worldBorders.kml"));
Document document = (Document) unmarshal.getFeature();
document.setName("JAK Example3");
Folder folder = (Folder) document.getFeature().get(0);
folder.setName("Mobile Phone Subscriptions 2008");

int folderSize = folder.getFeature().size();
// loop over all countries / Placemarks
for (int i = 0; i < folderSize; i++) {
Placemark placemark = (Placemark) folder.getFeature().get(i);
MultiGeometry multigeometry = (MultiGeometry) placemark.getGeometry();
double height = -1;
// only set height if data found in the HashMap (CSV)
if (data.containsKey(placemark.getId())) {
height = data.get(placemark.getId());
placemark.withDescription("" + (int) height);
// set a color gradient from yellow to red, calculating by the height, no transparency and no stroke/line
Utils.setDataValueColor(placemark, max, height, "FF", 1, null, ColorMode.NORMAL);
folder.addToFeature(placemark);
// normalize height and add minimal polygon height to prevent the "polygon hole problem"
height = ((height / max) * maxPolyHeight) + minPolyHeight;
} else {
// if no data found for the current country / Placemark, use no 3D polygon and set color to gray
Utils.setPolyStyleAndLineStyle(placemark, "FFCCCCCC", ColorMode.NORMAL, 1, null, ColorMode.NORMAL);
folder.addToFeature(placemark);
placemark.withDescription("no data");
}

for (int j = 0; j < multigeometry.getGeometry().size(); j++) {
Polygon polygon = (Polygon) multigeometry.getGeometry().get(j);
if (height < 0) {
// color overlay
polygon.setAltitudeMode(AltitudeMode.CLAMP_TO_GROUND);
polygon.setTessellate(Boolean.TRUE); // follow the terrain
} else {
// 3D polygon
polygon.setAltitudeMode(AltitudeMode.RELATIVE_TO_GROUND); // altitude can only be set in this mode
polygon.setExtrude(Boolean.TRUE); // connect to ground
}

// only for 3D polygons
if (height > 0) {
Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
LinearRing linearRing = outerBoundaryIs.getLinearRing();
List<Coordinate> coordinates = linearRing.getCoordinates();
// set the altitude of all vertices (height of the polygon)
for (Coordinate c : coordinates) {
c.setAltitude(height);
}
// check enclaves or polygons like it
if (!polygon.getInnerBoundaryIs().isEmpty()) {
for (int k = 0; k < polygon.getInnerBoundaryIs().size(); k++) {
Boundary innerBoundaryIs = polygon.getInnerBoundaryIs().get(k);
LinearRing linearRingInner = innerBoundaryIs.getLinearRing();
List<Coordinate> coordinatesInner = linearRingInner.getCoordinates();
// set the altitude of all vertices (height of the polygon)
for (Coordinate c : coordinatesInner) {
c.setAltitude(height);
}
}
}
}
}
}
unmarshal.marshal(new File("advancedexample3.kml"));
{code}

The full example is contained in JAK's sources ({{/JavaAPIforKML/src/test/java/de/micromata/jak/examples/Example3.java}}).


{column}
{column:width=1%}
{column}
{column:width=29%}

h6. Navigate space
{search-box}
[Java API for KML|Home] | [@Google|http://code.google.com/p/javaapiforkml/]
{pagetree}
{column}
{section}