Merge pull request #630 from krabaey/feature-kml-import

import keyhole markup language files
This commit is contained in:
vshcherb 2014-05-07 18:03:31 +02:00
commit a8b0329f51
4 changed files with 194 additions and 41 deletions

View file

@ -78,6 +78,12 @@
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\.gpx"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\.gpx"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\..*\\.gpx"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\..*\\..*\\.gpx"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.kml"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\.kml"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\.kml"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\..*\\.kml"/>
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kml"/>
</intent-filter>
<!-- google navigation intent -->

View file

@ -1,7 +1,9 @@
package net.osmand.plus.activities;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@ -36,6 +38,7 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.search.SearchActivity;
import net.osmand.plus.base.FailSafeFuntions;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.helpers.Kml2Gpx;
import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routing.RoutingHelper;
@ -340,7 +343,14 @@ public class MapActivity extends AccessibleActivity {
final String scheme = data.getScheme();
if ("file".equals(scheme))
{
showImportedGpx(data.getPath());
if (data.getPath().endsWith("kml"))
{
showImportedKml(new File(data.getPath()));
}
else
{
showImportedGpx(new File(data.getPath()));
}
}
else if("google.navigation".equals(scheme) || "osmand.navigation".equals(scheme))
{
@ -592,7 +602,7 @@ public class MapActivity extends AccessibleActivity {
mapLayers.updateLayers(mapView);
mapView.setComplexZoom(mapView.getZoom(), mapView.getSettingsZoomScale());
app.getDaynightHelper().startSensorIfNeeded(new StateChangedListener<Boolean>() {
@Override
public void stateChanged(Boolean change) {
getMapView().refreshMap(true);
@ -720,47 +730,79 @@ public class MapActivity extends AccessibleActivity {
getMapView().refreshMap();
}
private void showImportedGpx(final String gpxFile)
{
new AsyncTask<Void, Void, GPXFile>()
{
ProgressDialog progress = null;
private void showImportedGpx(final File gpxFile) {
new AsyncTask<Void, Void, GPXFile>() {
ProgressDialog progress = null;
@Override
protected void onPreExecute()
{
progress = ProgressDialog.show(MapActivity.this, getString(R.string.loading), getString(R.string.loading_data));
}
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(MapActivity.this, getString(R.string.loading), getString(R.string.loading_data));
}
@Override
protected GPXFile doInBackground(Void... nothing)
{
return GPXUtilities.loadGPXFile(getMyApplication(), new File(gpxFile));
}
@Override
protected GPXFile doInBackground(Void... nothing) {
return GPXUtilities.loadGPXFile(getMyApplication(), gpxFile);
}
@Override
protected void onPostExecute(GPXFile result)
{
progress.dismiss();
if (result != null)
{
if (result.warning != null)
{
AccessibleToast.makeText(MapActivity.this, result.warning, Toast.LENGTH_LONG).show();
}
else
{
getMyApplication().setGpxFileToDisplay(result, true);
final WptPt moveTo = result.findPointToShow();
if (moveTo != null)
{
mapView.getAnimatedDraggingThread().startMoving(moveTo.lat, moveTo.lon, mapView.getZoom(), true);
}
mapView.refreshMap();
}
@Override
protected void onPostExecute(GPXFile result) {
progress.dismiss();
if (result != null) {
if (result.warning != null) {
AccessibleToast.makeText(MapActivity.this, result.warning, Toast.LENGTH_LONG).show();
} else {
getMyApplication().setGpxFileToDisplay(result, true);
final WptPt moveTo = result.findPointToShow();
if (moveTo != null) {
mapView.getAnimatedDraggingThread().startMoving(moveTo.lat, moveTo.lon, mapView.getZoom(), true);
}
mapView.refreshMap();
}
}
}
}.execute();
}
}
}
}.execute();
}
private void showImportedKml(final File kmlFile) {
new AsyncTask<Void, Void, GPXFile>() {
ProgressDialog progress = null;
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(MapActivity.this, getString(R.string.loading), getString(R.string.loading_data));
}
@Override
protected GPXFile doInBackground(Void... nothing) {
final String result = Kml2Gpx.toGpx(kmlFile);
if (result == null) {
return null;
}
try {
return GPXUtilities.loadGPXFile(getMyApplication(), new ByteArrayInputStream(result.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
return null;
}
}
@Override
protected void onPostExecute(GPXFile result) {
progress.dismiss();
if (result != null) {
if (result.warning != null) {
AccessibleToast.makeText(MapActivity.this, result.warning, Toast.LENGTH_LONG).show();
} else {
getMyApplication().setGpxFileToDisplay(result, true);
final WptPt moveTo = result.findPointToShow();
if (moveTo != null) {
mapView.getAnimatedDraggingThread().startMoving(moveTo.lat, moveTo.lon, mapView.getZoom(), true);
}
mapView.refreshMap();
}
}
}
}.execute();
}
}

View file

@ -0,0 +1,42 @@
package net.osmand.plus.helpers;
import android.annotation.TargetApi;
import net.osmand.PlatformUtil;
import org.apache.commons.logging.Log;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.StringWriter;
/**
* @author Koen Rabaey
*/
public class Kml2Gpx {
public static final Log LOG = PlatformUtil.getLog(Kml2Gpx.class);
@TargetApi(8)
public static String toGpx(final File kml) {
try {
final Source xmlSource = new StreamSource(kml);
final Source xsltSource = new StreamSource(Kml2Gpx.class.getResourceAsStream("kml2gpx.xslt"));
final StringWriter sw = new StringWriter();
TransformerFactory.newInstance().newTransformer(xsltSource).transform(xmlSource, new StreamResult(sw));
return sw.toString();
} catch (TransformerConfigurationException e) {
LOG.error(e.toString(), e);
} catch (TransformerFactoryConfigurationError e) {
LOG.error(e.toString(), e);
} catch (TransformerException e) {
LOG.error(e.toString(), e);
}
return null;
}
}

View file

@ -0,0 +1,63 @@
<?xml version="1.0"?>
<!--
Copyright © Hugo Haas <hugoh@hugoh.net>
GNU General Public License, version 2 (GPL-2.0)
http://opensource.org/licenses/gpl-2.0.php
-->
<xsl:stylesheet version="1.0"
xmlns:kml="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
indent="yes" />
<xsl:template match="/">
<gpx version="1.1"
creator="kml2gpx.xslt"
xmlns="http://www.topografix.com/GPX/1/1">
<metadata>
<name><xsl:value-of select="kml:kml/kml:Document/kml:name"/></name>
<author>
<name>
<xsl:value-of select="kml:kml/kml:Document/atom:author/atom:author"/>
</name>
</author>
</metadata>
<xsl:for-each select="//gx:Track">
<trk>
<trkseg>
<xsl:for-each select="kml:when">
<!-- Timestamp -->
<xsl:variable name="ts" select="."/>
<!-- Coordinates -->
<xsl:variable name="lonlat" select="./following-sibling::gx:coord"/>
<xsl:variable name="lon" select="substring-before($lonlat,' ')"/>
<xsl:variable name="latele" select="substring-after($lonlat,' ')"/>
<xsl:variable name="lat">
<xsl:choose>
<xsl:when test="contains($latele,' ')">
<xsl:value-of select="substring-before($latele,' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$latele"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<trkpt lon="{$lon}" lat="{$lat}">
<time><xsl:value-of select="$ts"/></time>
</trkpt>
</xsl:for-each>
</trkseg>
</trk>
</xsl:for-each>
</gpx>
</xsl:template>
<xsl:template match="gx:Track">
</xsl:template>
</xsl:stylesheet>