diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/AbstractDocumentStorageImpl.java similarity index 100% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/AbstractDocumentStorageImpl.java diff --git a/tdt4140-gr1800/pom.xml b/tdt4140-gr1800/pom.xml index af5f7430f28b16335d916b807122504b3fcad862..1102480cdca09923ce759f1d199befb9914eaeed 100644 --- a/tdt4140-gr1800/pom.xml +++ b/tdt4140-gr1800/pom.xml @@ -15,5 +15,6 @@ <module>app.core</module> <module>FxMapControl</module> <module>app.ui</module> + <module>web.server</module> </modules> </project> \ No newline at end of file diff --git a/tdt4140-gr1800/web.server/.classpath b/tdt4140-gr1800/web.server/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..1e97e0a8f5945d79db4606d8520507033190fa1c --- /dev/null +++ b/tdt4140-gr1800/web.server/.classpath @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/webapp"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/tdt4140-gr1800/web.server/.project b/tdt4140-gr1800/web.server/.project new file mode 100644 index 0000000000000000000000000000000000000000..038c299b8dba8ed6f03d3ed02ae7176e97ba52ae --- /dev/null +++ b/tdt4140-gr1800/web.server/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>tdt4140.gr1800.web.server</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git a/tdt4140-gr1800/web.server/.settings/org.eclipse.jdt.core.prefs b/tdt4140-gr1800/web.server/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..13b3428acd87c3f94042e61eed221c15ce682bfa --- /dev/null +++ b/tdt4140-gr1800/web.server/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/tdt4140-gr1800/web.server/.settings/org.eclipse.m2e.core.prefs b/tdt4140-gr1800/web.server/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/tdt4140-gr1800/web.server/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/tdt4140-gr1800/web.server/pom.xml b/tdt4140-gr1800/web.server/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..57286633848e6cc761df3a89dd42d172e82c385e --- /dev/null +++ b/tdt4140-gr1800/web.server/pom.xml @@ -0,0 +1,108 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>tdt4140-gr1800.web.server</artifactId> + <packaging>war</packaging> + + <parent> + <groupId>tdt4140-gr1800</groupId> + <artifactId>tdt4140-gr1800</artifactId> + <version>0.0.1-SNAPSHOT</version> + </parent> + + <dependencies> + <dependency> + <groupId>tdt4140-gr1800</groupId> + <artifactId>tdt4140-gr1800.app.core</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>3.1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <version>2.9.3</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.9.3</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + <version>2.9.3</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-maven-plugin --> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-maven-plugin</artifactId> + <version>9.4.8.v20171121</version> + <configuration> + <scanIntervalSeconds>0</scanIntervalSeconds> + <stopKey>stopMe</stopKey> + <stopPort>9966</stopPort> + <systemProperties> + <systemProperty> + <name>data.locations</name> + <value>file:${project.basedir}/src/test/resources/tdt4140/gr1800/web/server/geoLocations.json</value> + </systemProperty> + </systemProperties> + </configuration> + <executions> + <execution> + <id>start-jetty</id> + <phase>pre-integration-test</phase> + <goals> + <goal>start</goal> + </goals> + </execution> + <execution> + <id>stop-jetty</id> + <phase>post-integration-test</phase> + <goals> + <goal>stop</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> <!-- for starting jetty for integration tests --> + <version>2.16</version> + <executions> + <execution> + <id>integration-test</id> + <goals> + <goal>integration-test</goal> + </goals> + </execution> + <execution> + <id>verify</id> + <goals> + <goal>verify</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java b/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..77b0534e907c89b0b89eefc3985dd939d4a3ea7e --- /dev/null +++ b/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java @@ -0,0 +1,69 @@ +package tdt4140.gr1800.web.server; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.stream.Collectors; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import io.jenetics.jpx.Person; +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.GeoLocationsPersistence; +import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; + +public class GeoServlet extends HttpServlet { + + private GeoLocationsPersistence persistence = new GeoLocationsJsonPersistence(); + + private Collection<GeoLocations> allGeoLocations = new ArrayList<GeoLocations>(); + + @Override + public void init() throws ServletException { + String dataLocationsProp = System.getProperty("data.locations"); + if (dataLocationsProp != null) { + String[] dataLocations = dataLocationsProp.split(","); + for (int i = 0; i < dataLocations.length; i++) { + try { + Collection<GeoLocations> geoLocations = persistence.loadLocations(new URL(dataLocations[i]).openStream()); + allGeoLocations.addAll(geoLocations); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } + } + super.init(); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String path = request.getPathInfo(); + Collection<GeoLocations> geoLocations = null; + if (path != null) { + if (path.startsWith("/")) { + path = path.substring(1); + } + String[] segments = path.split("\\/"); + if (segments.length == 1) { + geoLocations = allGeoLocations.stream().filter(geoLocation -> segments[0].equals(geoLocation.getName())).collect(Collectors.toList()); + } + } else { + geoLocations = allGeoLocations; + } + if (geoLocations == null) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + } else { + response.setContentType("application/json"); + response.setStatus(HttpServletResponse.SC_OK); + try (OutputStream output = response.getOutputStream()) { + persistence.saveLocations(geoLocations, output); + } catch (Exception e) { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } +} diff --git a/tdt4140-gr1800/web.server/src/main/webapp/WEB-INF/web.xml b/tdt4140-gr1800/web.server/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..1cbd3e31ca56bc7c99737eae4458bb12d3f9e6a6 --- /dev/null +++ b/tdt4140-gr1800/web.server/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" + metadata-complete="false" + version="3.1"> + + <servlet> + <servlet-name>GeoLocations</servlet-name> + <servlet-class>tdt4140.gr1800.web.server.GeoServlet</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>GeoLocations</servlet-name> + <url-pattern>/geo/*</url-pattern> + </servlet-mapping> + +</web-app> diff --git a/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java b/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java new file mode 100644 index 0000000000000000000000000000000000000000..3d00904a41c2caa41be6627c54bd7089bc7e612c --- /dev/null +++ b/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java @@ -0,0 +1,57 @@ +package tdt4140.gr1800.web.server; + +import java.io.InputStream; +import java.net.URL; +import java.util.Collection; +import java.util.Iterator; + +import org.junit.Assert; +import org.junit.Test; + +import tdt4140.gr1800.app.core.GeoLocated; +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.GeoLocationsPersistence; +import tdt4140.gr1800.app.core.LatLong; +import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; + +public class GeoLocationsServerIT { + + private GeoLocationsPersistence persistence = new GeoLocationsJsonPersistence(); + + private Collection<GeoLocations> get(String path, int size) throws Exception { + URL url = new URL("http://localhost:8080/geo" + path); + try (InputStream inputStream = url.openStream()) { + Collection<GeoLocations> geoLocations = persistence.loadLocations(inputStream); + Assert.assertEquals(size, geoLocations.size()); + return geoLocations; + } + } + + private LatLong[][] latLongs = { + { new LatLong(63, 10), new LatLong(63.1, 10.1)}, + { new LatLong(64, 11), new LatLong(64.1, 11.1)} + }; + + @Test + public void testGet() throws Exception { + Collection<GeoLocations> geoLocations = get("", 2); + Iterator<GeoLocations> it = geoLocations.iterator(); + checkGeoLocations(it.next(), "1", latLongs[0]); + checkGeoLocations(it.next(), "2", latLongs[1]); + + Collection<GeoLocations> geoLocations1 = get("/1", 1); + checkGeoLocations(geoLocations1.iterator().next(), "1", latLongs[0]); + Collection<GeoLocations> geoLocations2 = get("/2", 1); + checkGeoLocations(geoLocations2.iterator().next(), "2", latLongs[1]); + } + + private void checkGeoLocations(GeoLocations geoLocations, String name, LatLong... latLongs) { + Assert.assertEquals(name, geoLocations.getName()); + Iterator<GeoLocated> it = geoLocations.iterator(); + for (int i = 0; i < latLongs.length; i++) { + Assert.assertTrue(it.hasNext()); + latLongs[i].equalsLatLong(it.next()); + } + Assert.assertFalse(it.hasNext()); + } +} diff --git a/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-route.gpx b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-route.gpx new file mode 100644 index 0000000000000000000000000000000000000000..a006258ea21c91c5dedcb385650ec4abbee0ae9e --- /dev/null +++ b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-route.gpx @@ -0,0 +1,96 @@ +<?xml version="1.0"?> +<gpx + version="1.0" + creator="VB Net GPS: vermeiren-willy@pandora.be" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://www.topografix.com/GPX/1/0" + xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> + +<metadata> + <bounds minlat="51.396017" minlon="4.498043" maxlat="51.430402" maxlon="4.556108"/> +</metadata> + +<wpt lat="51.39709" lon="4.501519"> + <name>START</name> +</wpt> + +<rte> + <name>Achterbroek naar De Maatjes 13 km RT</name> + <rtept lat="51.39709" lon="4.501519"> + <name>1</name> + <cmt>1</cmt> + </rtept> + <rtept lat="51.398635" lon="4.502678"> + <name>2</name> + <cmt>2</cmt> + </rtept> + <rtept lat="51.405072" lon="4.498043"> + <name>3</name> + <cmt>3</cmt> + </rtept> + <rtept lat="51.417346" lon="4.515038"> + <name>4</name> + <cmt>4</cmt> + </rtept> + <rtept lat="51.41932" lon="4.513879"> + <name>5</name> + <cmt>5</cmt> + </rtept> + <rtept lat="51.421552" lon="4.523535"> + <name>6</name> + <cmt>6</cmt> + </rtept> + <rtept lat="51.423011" lon="4.522848"> + <name>7</name> + <cmt>7</cmt> + </rtept> + <rtept lat="51.423826" lon="4.5295"> + <name>8</name> + <cmt>8</cmt> + </rtept> + <rtept lat="51.427002" lon="4.528513"> + <name>9</name> + <cmt>9</cmt> + </rtept> + <rtept lat="51.430402" lon="4.552363"> + <name>10</name> + <cmt>10</cmt> + </rtept> + <rtept lat="51.426229" lon="4.555399"> + <name>11</name> + <cmt>11</cmt> + </rtept> + <rtept lat="51.426015" lon="4.554734"> + <name>12</name> + <cmt>12</cmt> + </rtept> + <rtept lat="51.423569" lon="4.556108"> + <name>13</name> + <cmt>13</cmt> + </rtept> + <rtept lat="51.41932" lon="4.546237"> + <name>14</name> + <cmt>14</cmt> + </rtept> + <rtept lat="51.410952" lon="4.534092"> + <name>15</name> + <cmt>15</cmt> + </rtept> + <rtept lat="51.406231" lon="4.543018"> + <name>16</name> + <cmt>16</cmt> + </rtept> + <rtept lat="51.396695" lon="4.515966"> + <name>17</name> + <cmt>17</cmt> + </rtept> + <rtept lat="51.396017" lon="4.515853"> + <name>18</name> + <cmt>18</cmt> + </rtept> + <rtept lat="51.397133" lon="4.502635"> + <name>19</name> + <cmt>19</cmt> + </rtept> +</rte> +</gpx> diff --git a/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-track.gpx b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-track.gpx new file mode 100644 index 0000000000000000000000000000000000000000..755f740e02199462cfa12b8a5243c73f49258786 --- /dev/null +++ b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/Achterbroek-track.gpx @@ -0,0 +1,100 @@ +<?xml version="1.0"?> +<gpx + version="1.0" + creator="VB Net GPS: vermeiren-willy@pandora.be" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://www.topografix.com/GPX/1/0" + xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> + +<metadata> + <bounds minlat="51.396017" minlon="4.498043" maxlat="51.430402" maxlon="4.556108"/> +</metadata> + +<wpt lat="51.39709" lon="4.501519"> + <name>START</name> +</wpt> + +<trk> + <name>Achterbroek naar De Maatjes 13 km TR</name> + <trkseg> + <trkpt lat="51.39709" lon="4.501519"> + <name>1</name> + </trkpt> + <trkpt lat="51.397705" lon="4.501452"> + <name>2</name> + </trkpt> + <trkpt lat="51.398635" lon="4.502678"> + <name>3</name> + </trkpt> + <trkpt lat="51.404042" lon="4.498472"> + <name>4</name> + </trkpt> + <trkpt lat="51.405072" lon="4.498043"> + <name>5</name> + </trkpt> + <trkpt lat="51.405456" lon="4.499259"> + <name>6</name> + </trkpt> + <trkpt lat="51.417346" lon="4.515038"> + <name>7</name> + </trkpt> + <trkpt lat="51.41932" lon="4.513879"> + <name>8</name> + </trkpt> + <trkpt lat="51.421552" lon="4.523535"> + <name>9</name> + </trkpt> + <trkpt lat="51.423011" lon="4.522848"> + <name>10</name> + </trkpt> + <trkpt lat="51.423826" lon="4.5295"> + <name>11</name> + </trkpt> + <trkpt lat="51.427002" lon="4.528513"> + <name>12</name> + </trkpt> + <trkpt lat="51.427131" lon="4.534478"> + <name>13</name> + </trkpt> + <trkpt lat="51.426819" lon="4.53744"> + <name>14</name> + </trkpt> + <trkpt lat="51.430402" lon="4.552363"> + <name>15</name> + </trkpt> + <trkpt lat="51.426229" lon="4.555399"> + <name>16</name> + </trkpt> + <trkpt lat="51.426015" lon="4.554734"> + <name>17</name> + </trkpt> + <trkpt lat="51.423569" lon="4.556108"> + <name>18</name> + </trkpt> + <trkpt lat="51.423097" lon="4.553981"> + <name>19</name> + </trkpt> + <trkpt lat="51.41932" lon="4.546237"> + <name>20</name> + </trkpt> + <trkpt lat="51.410952" lon="4.534092"> + <name>21</name> + </trkpt> + <trkpt lat="51.406231" lon="4.543018"> + <name>22</name> + </trkpt> + <trkpt lat="51.396695" lon="4.515966"> + <name>23</name> + </trkpt> + <trkpt lat="51.396017" lon="4.515853"> + <name>24</name> + </trkpt> + <trkpt lat="51.396858" lon="4.506495"> + <name>25</name> + </trkpt> + <trkpt lat="51.397133" lon="4.502635"> + <name>26</name> + </trkpt> + </trkseg> +</trk> +</gpx> diff --git a/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/geoLocations.json b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/geoLocations.json new file mode 100644 index 0000000000000000000000000000000000000000..bfda7a4524d5419067f9a0dba069740402aff30d --- /dev/null +++ b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/geoLocations.json @@ -0,0 +1,17 @@ +[ + { + "name" : "1", + "locations" : [ + { "latitude" : "63", "longitude" : "10" }, + [ "63.1", "10.1" ] + ] + }, + { + "name" : "2", + "path" : "true", + "locations" : [ + { "latitude" : "64", "longitude" : "11" }, + [ "64.1", "11.1" ] + ] + } +] diff --git a/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/sample1.gpx b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/sample1.gpx new file mode 100644 index 0000000000000000000000000000000000000000..79b840dd8808e6834ce6ef5fed1a6b428b3d0767 --- /dev/null +++ b/tdt4140-gr1800/web.server/src/test/resources/tdt4140/gr1800/web/server/sample1.gpx @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 400t" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"> + <metadata> + <link href="http://www.garmin.com"> + <text>Garmin International</text> + </link> + <time>2009-10-17T22:58:43Z</time> + </metadata> + <trk> + <name>Example GPX Document</name> + <trkseg> + <trkpt lat="47.644548" lon="-122.326897"> + <ele>4.46</ele> + <time>2009-10-17T18:37:26Z</time> + </trkpt> + <trkpt lat="47.644548" lon="-122.33"> + <ele>4.94</ele> + <time>2009-10-17T18:37:31Z</time> + </trkpt> + <trkpt lat="47.65" lon="-122.33"> + <ele>6.87</ele> + <time>2009-10-17T18:37:34Z</time> + </trkpt> + </trkseg> + </trk> +</gpx>