-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix for #1350: Add support for GPX tracks with multiple segments
- Loading branch information
bohare
committed
May 30, 2017
1 parent
b936a84
commit c255821
Showing
12 changed files
with
1,810 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,68 @@ | ||
from django.contrib.gis.gdal import DataSource | ||
from django.contrib.gis.geos import GeometryCollection | ||
import logging | ||
|
||
KEEP_LAYERS = ['tracks', 'routes', 'waypoints'] | ||
import gpxpy | ||
from django.contrib.gis.geos import (GeometryCollection, LineString, | ||
MultiLineString, MultiPoint, Point) | ||
from django.utils.translation import ugettext as _ | ||
|
||
from ..exceptions import InvalidGPXFile | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class GPXProcessor: | ||
|
||
def __init__(self, gpx_file): | ||
self.ds = DataSource(gpx_file) | ||
with open(gpx_file) as f: | ||
try: | ||
self.gpx = gpxpy.parse(f) | ||
except gpxpy.gpx.GPXException as e: | ||
logger.exception(e) | ||
raise InvalidGPXFile(_("Invalid GPX file: %s" % e)) | ||
|
||
def get_layers(self): | ||
layers = {} | ||
for layer in self.ds: | ||
name = layer.name | ||
if name in KEEP_LAYERS: | ||
# geom = self._get_features(layer) | ||
layers[name] = GeometryCollection(layer.get_geoms(geos=True)) | ||
if self.gpx.tracks: | ||
layers['tracks'] = GeometryCollection( | ||
MultiLineString(parse_tracks(self.gpx.tracks)) | ||
) | ||
if self.gpx.routes: | ||
layers['routes'] = GeometryCollection( | ||
MultiLineString(parse_routes(self.gpx.routes)) | ||
) | ||
if self.gpx.waypoints: | ||
layers['waypoints'] = GeometryCollection( | ||
MultiPoint(parse_waypoints(self.gpx.waypoints)) | ||
) | ||
if not layers: | ||
raise InvalidGPXFile( | ||
_("Error parsing GPX file: no geometry found.")) | ||
|
||
return layers | ||
|
||
|
||
def parse_segment(segment): | ||
return [Point(p.longitude, p.latitude).coords for p in segment.points] | ||
|
||
|
||
def parse_tracks(tracks): | ||
multiline = [] | ||
for track in tracks: | ||
for segment in track.segments: | ||
points = parse_segment(segment) | ||
if len(points) > 1: | ||
multiline.append(LineString(points)) | ||
return multiline | ||
|
||
|
||
def parse_waypoints(waypoints): | ||
return [Point(point.longitude, point.latitude) for point in waypoints] | ||
|
||
|
||
def parse_routes(routes): | ||
multiline = [] | ||
for route in routes: | ||
points = parse_segment(route) | ||
if len(points) > 1: | ||
multiline.append(LineString(points)) | ||
return multiline |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
<?xml version="2.0" encoding="UTF-8" standalone="no" ?><!-- invalid version only 1.0 or 1.1 supported --> | ||
<gpx | ||
xmlns="http://www.topografix.com/GPX/1/1" | ||
xmlns:gpxx="http://www.garmin.com/xmlschemas/WaypointExtension/v1" | ||
xmlns:gpxtrx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" | ||
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" | ||
creator="Oregon 550" | ||
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/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.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>2016-05-18T09:20:06Z</time> | ||
</metadata> | ||
<wpt lat="52.941277" lon="-8.034792"> | ||
<ele>159.297363</ele> | ||
<time>2016-05-18T09:20:06Z</time> | ||
<name>001</name> | ||
<sym>Lodging</sym> | ||
</wpt> | ||
<wpt lat="52.946419" lon="-8.039001"> | ||
<ele>88.808327</ele> | ||
<time>2016-05-18T10:04:17Z</time> | ||
<name>002</name> | ||
<sym>Lodging</sym> | ||
</wpt> | ||
<wpt lat="52.946421" lon="-8.039008"> | ||
<ele>89.445007</ele> | ||
<time>2016-05-18T10:06:58Z</time> | ||
<name>003</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946064" lon="-8.038319"> | ||
<ele>87.765770</ele> | ||
<time>2016-05-18T10:08:56Z</time> | ||
<name>004</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946153" lon="-8.037743"> | ||
<ele>88.544846</ele> | ||
<time>2016-05-18T10:09:42Z</time> | ||
<name>005</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946521" lon="-8.037001"> | ||
<ele>90.230118</ele> | ||
<time>2016-05-18T10:10:45Z</time> | ||
<name>006</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946283" lon="-8.036948"> | ||
<ele>91.034340</ele> | ||
<time>2016-05-18T10:11:28Z</time> | ||
<name>007</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946500" lon="-8.036520"> | ||
<ele>90.365944</ele> | ||
<time>2016-05-18T10:12:52Z</time> | ||
<name>008</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946646" lon="-8.036945"> | ||
<ele>91.291801</ele> | ||
<time>2016-05-18T10:14:18Z</time> | ||
<name>009</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946733" lon="-8.037329"> | ||
<ele>92.031578</ele> | ||
<time>2016-05-18T10:14:57Z</time> | ||
<name>010</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946578" lon="-8.037304"> | ||
<ele>89.177856</ele> | ||
<time>2016-05-18T10:15:30Z</time> | ||
<name>011</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946655" lon="-8.037608"> | ||
<ele>88.838951</ele> | ||
<time>2016-05-18T10:16:14Z</time> | ||
<name>012</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946620" lon="-8.037936"> | ||
<ele>89.070808</ele> | ||
<time>2016-05-18T10:16:53Z</time> | ||
<name>013</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946616" lon="-8.037954"> | ||
<ele>92.048050</ele> | ||
<time>2016-05-18T10:17:13Z</time> | ||
<name>014</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946628" lon="-8.037980"> | ||
<ele>88.055138</ele> | ||
<time>2016-05-18T10:17:40Z</time> | ||
<name>015</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
<wpt lat="52.946757" lon="-8.037970"> | ||
<ele>89.512466</ele> | ||
<time>2016-05-18T10:18:39Z</time> | ||
<name>016</name> | ||
<sym>Crossing</sym> | ||
</wpt> | ||
</gpx> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?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/WaypointExtension/v1" | ||
xmlns:gpxtrx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" | ||
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" | ||
creator="Oregon 550" | ||
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/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.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>2016-09-01T08:50:59Z</time> | ||
</metadata> | ||
<rte> | ||
<name>TEST</name> | ||
<rtept lat="52.946419" lon="-8.039839"> | ||
<name>05973230688404</name> | ||
</rtept> | ||
<rtept lat="53.063194" lon="-8.229833"> | ||
<name>Lough Derg</name> | ||
</rtept> | ||
<rtept lat="53.537029" lon="-7.907280"> | ||
<name>06061460754125</name> | ||
</rtept> | ||
<rtept lat="54.116417" lon="-8.027824"> | ||
<name>05981810818596</name> | ||
</rtept> | ||
</rte> | ||
<trk> | ||
<trkseg> | ||
<trkpt lat="45.5366218" lon="-122.5179408"> | ||
<ele>67.0</ele> | ||
<time>2017-03-27T20:48:01Z</time> | ||
<hdop>3.0</hdop> | ||
</trkpt> | ||
<trkpt lat="45.5367998" lon="-122.5180683"> | ||
<ele>56.0</ele> | ||
<time>2017-03-27T20:48:16Z</time> | ||
<hdop>3.0</hdop> | ||
<extensions> | ||
<speed>1.5299999713897705</speed> | ||
</extensions> | ||
</trkpt> | ||
</trkseg> | ||
<trkseg> | ||
<trkpt lat="45.5368517" lon="-122.5180993"> | ||
<ele>59.0</ele> | ||
<time>2017-03-27T20:48:23Z</time> | ||
<hdop>4.0</hdop> | ||
<extensions> | ||
<speed>0.47999998927116394</speed> | ||
</extensions> | ||
</trkpt> | ||
</trkseg> | ||
</trk> | ||
</gpx> |
Oops, something went wrong.