package org.osmdroid.bonuspack.kml; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.osmdroid.bonuspack.kml.KmlFeature.Styler; import org.osmdroid.util.BoundingBox; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView; import org.osmdroid.views.overlay.Marker; import org.osmdroid.views.overlay.Marker.OnMarkerDragListener; import org.osmdroid.views.overlay.Overlay; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; /** * KML and/or GeoJSON Point * @author M.Kergall */ public class KmlPoint extends KmlGeometry implements Parcelable, Cloneable { public KmlPoint(){ super(); } public KmlPoint(GeoPoint position){ this(); setPosition(position); } /** GeoJSON constructor */ public KmlPoint(JsonObject json){ this(); JsonElement coordinates = json.get("coordinates"); if (coordinates != null){ setPosition(KmlGeometry.parseGeoJSONPosition(coordinates.getAsJsonArray())); } } public void setPosition(GeoPoint position){ if (mCoordinates == null){ mCoordinates = new ArrayList<GeoPoint>(1); mCoordinates.add(position); } else mCoordinates.set(0, position); } public GeoPoint getPosition(){ return mCoordinates.get(0); } /** default listener for dragging a Marker built from a KML Point */ public class OnKMLMarkerDragListener implements OnMarkerDragListener { @Override public void onMarkerDrag(Marker marker) {} @Override public void onMarkerDragEnd(Marker marker) { Object object = marker.getRelatedObject(); if (object != null && object instanceof KmlPoint){ KmlPoint point = (KmlPoint)object; point.setPosition(marker.getPosition()); } } @Override public void onMarkerDragStart(Marker marker) {} } public void applyDefaultStyling(Marker marker, Style defaultStyle, KmlPlacemark kmlPlacemark, KmlDocument kmlDocument, MapView map){ Context context = map.getContext(); Style style = kmlDocument.getStyle(kmlPlacemark.mStyle); if (style != null && style.mIconStyle != null){ style.mIconStyle.styleMarker(marker, context); } else if (defaultStyle!=null && defaultStyle.mIconStyle!=null){ defaultStyle.mIconStyle.styleMarker(marker, context); } //allow marker drag, acting on KML Point: marker.setDraggable(true); marker.setOnMarkerDragListener(new OnKMLMarkerDragListener()); marker.setEnabled(kmlPlacemark.mVisibility); } /** Build the corresponding Marker overlay */ @Override public Overlay buildOverlay(MapView map, Style defaultStyle, Styler styler, KmlPlacemark kmlPlacemark, KmlDocument kmlDocument){ Marker marker = new Marker(map); marker.setTitle(kmlPlacemark.mName); marker.setSnippet(kmlPlacemark.mDescription); marker.setSubDescription(kmlPlacemark.getExtendedDataAsText()); marker.setPosition(getPosition()); //keep the link from the marker to the KML feature: marker.setRelatedObject(this); if (styler == null){ applyDefaultStyling(marker, defaultStyle, kmlPlacemark, kmlDocument, map); } else styler.onPoint(marker, kmlPlacemark, this); return marker; } @Override public void saveAsKML(Writer writer){ try { writer.write("<Point>\n"); writeKMLCoordinates(writer, mCoordinates); writer.write("</Point>\n"); } catch (IOException e) { e.printStackTrace(); } } @Override public JsonObject asGeoJSON(){ JsonObject json = new JsonObject(); json.addProperty("type", "Point"); json.add("coordinates", KmlGeometry.geoJSONPosition(mCoordinates.get(0))); return json; } @Override public BoundingBox getBoundingBox(){ return BoundingBox.fromGeoPoints(mCoordinates); } //Cloneable implementation ------------------------------------ @Override public KmlPoint clone(){ return (KmlPoint)super.clone(); } //Parcelable implementation ------------ @Override public int describeContents() { return 0; } //@Override public void writeToParcel(Parcel out, int flags) { // super.writeToParcel(out, flags); //} public static final Creator<KmlPoint> CREATOR = new Creator<KmlPoint>() { @Override public KmlPoint createFromParcel(Parcel source) { return new KmlPoint(source); } @Override public KmlPoint[] newArray(int size) { return new KmlPoint[size]; } }; public KmlPoint(Parcel in){ super(in); } }