Voici un problème qui m’a pris pas mal de temps à résoudre…. J’ai donc décidé après une longue absence, de vous faire partager ma solution qui n’ai peut être pas la meilleure mais qui a le mérite de fonctionner! :p

Tout d’abord, voici la définition exacte de KML selon wikipédia: KML (Keyhole Markup Language) que l’on peut traduire par « langage à base de balises géolocales », est un langage basé sur le formalisme XML et destiné à la gestion de l’affichage de données géospatiales dans les logiciels Google Earth, Google Maps, Google Mobile et World Wind.

Dans un précédent tutoriel, je parsais un fichier XML à l’aide de SAX. Ce parsing à le mérite d’être très adaptable mais est vraiment très compliqué à mettre en place.

J’ai donc cherché une librairie qui me permettrais de simplifier cela car j’ai eu besoin de parser du KML qui est vraiment très complexe. Je me suis basé sur SimpleXML.

Cette librairie permet de faire de la sérialisation/dé-sérialisation. Ainsi on doit créer un modèle de données sous forme de classe qui correspond exactement au modèle XML.

J’ai donc créé un modèle de classes collant au format KML.

Voici les classes java:

Voici la classe Kml.java

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

// Ici on met le tag @Root car c'est le premier élément (la racine) du fichier XML
@Root(name="kml")
public class Kml {

	// Le tag Element correspond comme sont nom l'indique à un élément entre crochet ("") dans le fichier XML
	@Element
	private Document Document;

	public kml() {
		super();
	}

	public kml(Document Document) {
		super();
		this.Document = Document;
	}

	public Document getDocument() {
		return Document;
	}

	public void setDocument(Document Document) {
		this.Document = Document;
	}
}

Fichier Document.java

import java.util.List;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;

public class Document {

	// Le tag ElementList permet de définir une liste d'éléments
	// Ensuite on a des attributs: entry permet de définir à quelle élément fait référence la liste,
        // inline permet créer une liste avec des éléments qui ne sont pas exclusivement entre balises.
        // C'est à dire que ces éléments sont mêlés avec d'autre éléments entre les mêmes balises.
        // l'attribut required quant à lui permet de définir si l'élément est obligatoire ou pas
	@ElementList(entry="Placemark",inline=true,required=false)
	private List
 Placemark;

	@Element(required=false)
	private String name;

	@Element(required=false)
	private Style Style;

	// L'attribut data permet de signaler que l'élément contient une section (  getPlacemarks() {
		return Placemark;
	}

	public void setPlacemarks(List
 placemarks) {
		this.Placemark = placemarks;
	}
}

Voici le fichier Placemark.java

import java.util.List;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

import fr.blueapps.bluetech.core.BTCore;

@Root
public class Placemark {

	@Element(required=false)
	private String name;

	@Element(data=true,required=false)
	private String description;

	@Element(required=false)
	private String address;

	// Ici nous n'avons pas besoin de l'attribut inline car les éléments ne sont pas mêlés à d'autres
	@ElementList(required=false)
	private List
 StyleMap;

	@Element(required=false)
	private Point Point;

	@Element(required=false)
	private LookAt LookAt;

	@Element(required=false)
	private GeometryCollection GeometryCollection;

	@Element(required=false)
	private String styleUrl;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public List
 getStyleMap() {
		return StyleMap;
	}

	public void setStyleMap(List
 styleMap) {
		this.StyleMap = styleMap;
	}

	public Point getPoint() {
		return Point;
	}

	public void setPoint(Point point) {
		this.Point = point;
	}

	public LookAt getLookAt() {
		return LookAt;
	}

	public void setLookAt(LookAt lookAt) {
		this.LookAt = lookAt;
	}

	public GeometryCollection getGeometryCollection() {
		return GeometryCollection;
	}

	public void setGeometryCollection(GeometryCollection geometryCollection) {
		GeometryCollection = geometryCollection;
	}

	public String getStyleUrl() {
		return styleUrl;
	}

	public void setStyleUrl(String styleUrl) {
		this.styleUrl = styleUrl;
	}
}

Voici le fichier Pair.java

import org.simpleframework.xml.Element;

public class Pair {
	@Element
	private String key;

	@Element
	private Style Style;

	public Pair() {
		super();
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public Style getStyle() {
		return Style;
	}

	public void setStyle(Style style) {
		this.Style = style;
	}

}

Voici le fichier Point.java

import org.simpleframework.xml.Element;

public class Point {

	@Element
	private String coordinates;

	public Point() {
		super();
	}

	public Point(String coordinates) {
		super();
		this.coordinates = coordinates;
	}

	public String getCoordinates() {
		return coordinates;
	}

	public void setCoordinates(String coordinates) {
		this.coordinates = coordinates;
	}
}

Voici le fichier LookAt.java

import org.simpleframework.xml.Element;

public class LookAt {

	@Element
	private double longitude;

	@Element
	private double latitude;

	@Element(required=false)
	private double range;

	@Element(required=false)
	private double tilt;

	@Element(required=false)
	private double heading;

	public LookAt() {
		super();
	}

	public LookAt(double longitude, double latitude, double range, double tilt,
			double heading) {
		super();
		this.longitude = longitude;
		this.latitude = latitude;
		this.range = range;
		this.tilt = tilt;
		this.heading = heading;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public double getRange() {
		return range;
	}

	public void setRange(double range) {
		this.range = range;
	}

	public double getTilt() {
		return tilt;
	}

	public void setTilt(double tilt) {
		this.tilt = tilt;
	}

	public double getHeading() {
		return heading;
	}

	public void setHeading(double heading) {
		this.heading = heading;
	}
}

Voici le fichier GeometryCollection.java

import org.simpleframework.xml.Element;

public class GeometryCollection {

	@Element(required=false)
	private LineString LineString;

	public GeometryCollection() {
		super();
	}

	public GeometryCollection(LineString lineString) {
		super();
		LineString = lineString;
	}

	public LineString getLineString() {
		return LineString;
	}

	public void setLineString(LineString lineString) {
		LineString = lineString;
	}
}

Voici le fichier LineString.java

import org.simpleframework.xml.Element;

public class LineString {

	@Element(required=false)
	private String coordinates;

	public LineString() {
		super();
	}

	public LineString(String coordinates) {
		super();
		this.coordinates = coordinates;
	}

	public String getCoordinates() {
		return coordinates;
	}

	public void setCoordinates(String coordinates) {
		this.coordinates = coordinates;
	}

}

Voici le fichier Style.java

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;

public class Style {

	@Attribute(required=false)
	private String id;

	@Element(required=false)
	private LineStyle LineStyle;

	@Element(required=false)
	private IconStyle IconStyle;

	@Element(required=false)
	private ListStyle ListStyle;

	public Style() {
		super();
	}

	public Style(String id, LineStyle linestyle, IconStyle iconStyle,
			ListStyle listStyle) {
		super();
		this.id = id;
		LineStyle = linestyle;
		this.IconStyle = iconStyle;
		ListStyle = listStyle;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public LineStyle getLinestyle() {
		return LineStyle;
	}

	public void setLinestyle(LineStyle linestyle) {
		this.LineStyle = linestyle;
	}

	public IconStyle getIconStyle() {
		return IconStyle;
	}

	public void setIconStyle(IconStyle iconStyle) {
		this.IconStyle = iconStyle;
	}

	public ListStyle getListStyle() {
		return ListStyle;
	}

	public void setListStyle(ListStyle listStyle) {
		ListStyle = listStyle;
	}

}

Voici le fichier LineStyle.java

import org.simpleframework.xml.Element;

public class LineStyle {

	@Element(required=false)
	private String color;

	@Element(required=false)
	private String width;

	public LineStyle() {
		super();
	}

	public LineStyle(String color, String width) {
		super();
		this.color = color;
		this.width = width;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public String getWidth() {
		return width;
	}

	public void setWidth(String width) {
		this.width = width;
	}

}

Voici le fichier ListStyle.java

import org.simpleframework.xml.Element;

public class ListStyle {

	@Element(required=false)
	private ItemIcon ItemIcon;

	public ListStyle() {
		super();
	}

	public ListStyle(ItemIcon itemIcon) {
		super();
		ItemIcon = itemIcon;
	}

	public ItemIcon getItemIcon() {
		return ItemIcon;
	}

	public void setItemIcon(ItemIcon itemIcon) {
		ItemIcon = itemIcon;
	}

}

Voici le fichier IconStyle.java

import org.simpleframework.xml.Element;

public class IconStyle {

	@Element(required=false)
	private Icon Icon;

	@Element(required=false)
	private hotSpot hotSpot;

	@Element(required=false)
	private double scale;

	public IconStyle() {
		super();
	}

	public IconStyle(Icon icon, hotSpot hotSpot, double scale) {
		super();
		this.Icon = icon;
		this.hotSpot = hotSpot;
		this.scale = scale;
	}

	public Icon getIcon() {
		return Icon;
	}

	public void setIcon(Icon icon) {
		this.Icon = icon;
	}

	public hotSpot getHotSpot() {
		return hotSpot;
	}

	public void setHotSpot(hotSpot hotSpot) {
		this.hotSpot = hotSpot;
	}

	public double getScale() {
		return scale;
	}

	public void setScale(double scale) {
		this.scale = scale;
	}
}

Voici le fichier Icon.java

import org.simpleframework.xml.Element;

public class Icon {

	@Element
	private String href;

	public Icon() {
		super();
	}

	public Icon(String href) {
		super();
		this.href = href;
	}

	public String getHref() {
		return href;
	}

	public void setHref(String href) {
		this.href = href;
	}

}

Voici le fichier hotSpot.java

import org.simpleframework.xml.Attribute;

public class hotSpot {

	@Attribute
	private double x;

	@Attribute
	private double y; 

	@Attribute
	private String xunits;

	@Attribute
	private String yunits;

	public hotSpot() {
		super();
	}

	public hotSpot(double x, double y, String xunits, String yunits) {
		super();
		this.x = x;
		this.y = y;
		this.xunits = xunits;
		this.yunits = yunits;
	}

}

Voici le fichier ItemIcon.java

import org.simpleframework.xml.Element;

public class ItemIcon {

	@Element
	private String href;

	public ItemIcon() {
		super();
	}

	public ItemIcon(String href) {
		super();
		this.href = href;
	}

	public String getHref() {
		return href;
	}

	public void setHref(String href) {
		this.href = href;
	}

}

Ca y est, nous avons notre modèle de données!!! Félicitations!

Vous allez voir, il ne reste plus grand chose à faire… :)

HttpURLConnection urlConnection= null;
try {
	URL URL = null;
	try {
		URL = new URL(url.toString());
	} catch (Exception e) {
		e.printStackTrace();
}
try {
	urlConnection=(HttpURLConnection)URL.openConnection();
} catch (Exception e) {
	e.printStackTrace();
}
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
try {
	urlConnection.connect();
} catch (Exception e) {
	e.printStackTrace();
}
InputStream is = urlConnection.getInputStream();
Serializer serializer = new Persister();

try {
	kml = serializer.read(Kml.class, is);
} catch (Exception e) {
	e.printStackTrace();
}
List
 _placemarks = kml.getDocument().getPlacemarks();

Ca y est! Vous avez votre instance de KML qui est remplie à partir de votre fichier KML!

A bientôt!

PS: Comme d’habitude, si vous avez des questions, n’hésitez pas, j’essaierais de vous répondre!