def test_prepare_xml_read(data, result): xml = prepare_xml_read(data) assert xml.find('tag').text == result
def import_locations(self, gpx_file, gpx_version=None): """Import GPX data files `import_locations()` returns a series of lists representing track segments with `Trackpoint` objects as contents. It expects data files in GPX format, as specified in `GPX 1.1 Schema Documentation <http://www.topografix.com/GPX/1/1/>`__, which is XML such as:: <?xml version="1.0" encoding="utf-8" standalone="no"?> <gpx version="1.1" creator="PocketGPSWorld.com" xmlns="http://www.topografix.com/GPX/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"> <trk> <trkseg> <trkpt lat="52.015" lon="-0.221"> <name>Home</name> <desc>My place</desc> </trkpt> <trkpt lat="52.167" lon="0.390"> <name>MSR</name> <desc>Microsoft Research, Cambridge</desc> </trkpt> </trkseg> </trk> </gpx> The reader uses `Python <http://www.python.org/>`__'s `ElementTree` module, so should be very fast when importing data. The above file processed by `import_locations()` will return the following `list` object:: [[Trackpoint(52.015, -0.221, "Home", "My place"), Trackpoint(52.167, 0.390, "MSR", "Microsoft Research, Cambridge")], ] >>> trackpoints = Trackpoints(open("gpx_tracks")) >>> for value in sorted(trackpoints[0], ... key=lambda x: x.name.lower()): ... print(value) Home (52°00'54"N, 000°13'15"W) [My place] MSR (52°10'01"N, 000°23'24"E) [Microsoft Research, Cambridge] :Parameters: gpx_file : `file`, `list` or `str` GPX data to read gpx_version : `str` Specific GPX version entities to import :rtype: `list` :return: Locations with optional comments """ data = utils.prepare_xml_read(gpx_file) if gpx_version: try: accepted_gpx = {gpx_version: GPX_VERSIONS[gpx_version]} except KeyError: raise KeyError("Unknown GPX version `%s'" % gpx_version) else: accepted_gpx = GPX_VERSIONS for version, namespace in accepted_gpx.items(): logging.info("Searching for GPX v%s entries" % version) gpx_elem = lambda name: ET.QName(namespace, name).text segment_elem = "//" + gpx_elem("trkseg") trackpoint_elem = gpx_elem("trkpt") name_elem = gpx_elem("name") desc_elem = gpx_elem("desc") for segment in data.findall(segment_elem): points = point.Points() for trackpoint in segment.findall(trackpoint_elem): latitude = trackpoint.get("lat") longitude = trackpoint.get("lon") name = trackpoint.findtext(name_elem) description = trackpoint.findtext(desc_elem) points.append(Trackpoint(latitude, longitude, name, description)) self.append(points)
def import_locations(self, gpx_file): """Import GPX data files. ``import_locations()`` returns a series of lists representing track segments with :class:`Routepoint` objects as contents. It expects data files in GPX format, as specified in `GPX 1.1 Schema Documentation`_, which is XML such as:: <?xml version="1.0" encoding="utf-8" standalone="no"?> <gpx version="1.1" creator="upoints/0.12.2" xmlns="http://www.topografix.com/GPX/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"> <rte> <rtept lat="52.015" lon="-0.221"> <name>Home</name> <desc>My place</desc> </rtept> <rtept lat="52.167" lon="0.390"> <name>MSR</name> <desc>Microsoft Research, Cambridge</desc> </rtept> </rte> </gpx> The reader uses the :mod:`ElementTree` module, so should be very fast when importing data. The above file processed by ``import_locations()`` will return the following ``list`` object:: [[Routepoint(52.015, -0.221, "Home", "My place"), Routepoint(52.167, 0.390, "MSR", "Microsoft Research, Cambridge")], ] :type gpx_file: ``file``, ``list`` or ``str`` :param gpx_file: GPX data to read :rtype: ``list`` :return: Locations with optional comments .. _GPX 1.1 Schema Documentation: http://www.topografix.com/GPX/1/1/ """ self._gpx_file = gpx_file data = utils.prepare_xml_read(gpx_file, objectify=True) try: self.metadata.import_metadata(data.metadata) except AttributeError: pass for route in data.rte: points = point.TimedPoints() for routepoint in route.rtept: latitude = routepoint.get('lat') longitude = routepoint.get('lon') try: name = routepoint.name.text except AttributeError: name = None try: description = routepoint.desc.text except AttributeError: description = None try: elevation = float(routepoint.ele.text) except AttributeError: elevation = None try: time = utils.Timestamp.parse_isoformat(routepoint.time.text) except AttributeError: time = None points.append(Routepoint(latitude, longitude, name, description, elevation, time)) self.append(points)
def import_locations(self, osm_file): """Import OSM data files. ``import_locations()`` returns a list of ``Node`` and ``Way`` objects. It expects data files conforming to the `OpenStreetMap 0.5 DTD`_, which is XML such as:: <?xml version="1.0" encoding="UTF-8"?> <osm version="0.5" generator="upoints/0.9.0"> <node id="0" lat="52.015749" lon="-0.221765" user="******" visible="true" timestamp="2008-01-25T12:52:11+00:00" /> <node id="1" lat="52.015761" lon="-0.221767" visible="true" timestamp="2008-01-25T12:53:00+00:00"> <tag k="created_by" v="hand" /> <tag k="highway" v="crossing" /> </node> <node id="2" lat="52.015754" lon="-0.221766" user="******" visible="true" timestamp="2008-01-25T12:52:30+00:00"> <tag k="amenity" v="pub" /> </node> <way id="0" visible="true" timestamp="2008-01-25T13:00:00+0000"> <nd ref="0" /> <nd ref="1" /> <nd ref="2" /> <tag k="ref" v="My Way" /> <tag k="highway" v="primary" /> </way> </osm> The reader uses the :mod:`ElementTree` module, so should be very fast when importing data. The above file processed by ``import_locations()`` will return the following `Osm` object:: Osm([ Node(0, 52.015749, -0.221765, True, "jnrowe", utils.Timestamp(2008, 1, 25, 12, 52, 11), None), Node(1, 52.015761, -0.221767, True, utils.Timestamp(2008, 1, 25, 12, 53), None, {"created_by": "hand", "highway": "crossing"}), Node(2, 52.015754, -0.221766, True, "jnrowe", utils.Timestamp(2008, 1, 25, 12, 52, 30), {"amenity": "pub"}), Way(0, [0, 1, 2], True, None, utils.Timestamp(2008, 1, 25, 13, 00), {"ref": "My Way", "highway": "primary"})], generator="upoints/0.9.0") :type osm_file: ``file``, ``list`` or ``str`` :param osm_file: OpenStreetMap data to read :rtype: ``Osm`` :return: Nodes and ways from the data .. _OpenStreetMap 0.5 DTD: http://wiki.openstreetmap.org/wiki/OSM_Protocol_Version_0.5/DTD """ self._osm_file = osm_file data = utils.prepare_xml_read(osm_file, objectify=True) # This would be a lot simpler if OSM exports defined a namespace if not data.tag == 'osm': raise ValueError("Root element %r is not `osm'" % data.tag) self.version = data.get('version') if not self.version: raise ValueError('No specified OSM version') elif not self.version == '0.5': raise ValueError('Unsupported OSM version %r' % data) self.generator = data.get('generator') for elem in data.getchildren(): if elem.tag == 'node': self.append(Node.parse_elem(elem)) elif elem.tag == 'way': self.append(Way.parse_elem(elem))
def import_locations(self, gpx_file, gpx_version=None): """Import GPX data files ``import_locations()`` returns a series of lists representing track segments with :class:`Routepoint` objects as contents. It expects data files in GPX format, as specified in `GPX 1.1 Schema Documentation`_, which is XML such as:: <?xml version="1.0" encoding="utf-8" standalone="no"?> <gpx version="1.1" creator="upoints/0.11.0" xmlns="http://www.topografix.com/GPX/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"> <rte> <rtept lat="52.015" lon="-0.221"> <name>Home</name> <desc>My place</desc> </rtept> <rtept lat="52.167" lon="0.390"> <name>MSR</name> <desc>Microsoft Research, Cambridge</desc> </rtept> </rte> </gpx> The reader uses the :mod:`ElementTree` module, so should be very fast when importing data. The above file processed by ``import_locations()`` will return the following ``list`` object:: [[Routepoint(52.015, -0.221, "Home", "My place"), Routepoint(52.167, 0.390, "MSR", "Microsoft Research, Cambridge")], ] >>> routepoints = Routepoints(open("gpx_routes")) >>> for value in sorted(routepoints[0], ... key=attrgetter("name")): ... print(value) Home (52°00'54"N, 000°13'15"W on 2008-07-26T00:00:00+00:00) [My place] MSR (52°10'01"N, 000°23'24"E on 2008-07-27T00:00:00+00:00) [Microsoft Research, Cambridge] :type gpx_file: ``file``, ``list`` or ``str`` :param gpx_file: GPX data to read :type gpx_version: ``str`` :param gpx_version: Specific GPX version entities to import :rtype: ``list`` :return: Locations with optional comments .. _GPX 1.1 Schema Documentation: http://www.topografix.com/GPX/1/1/ """ self._gpx_file = gpx_file data = utils.prepare_xml_read(gpx_file) if gpx_version: try: accepted_gpx = {gpx_version: GPX_VERSIONS[gpx_version]} except KeyError: raise KeyError("Unknown GPX version `%s'" % gpx_version) else: accepted_gpx = GPX_VERSIONS for version, namespace in accepted_gpx.items(): logging.info("Searching for GPX v%s entries" % version) gpx_elem = lambda name: ET.QName(namespace, name).text metadata = data.find("//" + gpx_elem("metadata")) if metadata: self.metadata.import_metadata(metadata) route_elem = "//" + gpx_elem("rte") routepoint_elem = gpx_elem("rtept") name_elem = gpx_elem("name") desc_elem = gpx_elem("desc") elev_elem = gpx_elem("ele") time_elem = gpx_elem("time") for route in data.findall(route_elem): points = point.TimedPoints() for routepoint in route.findall(routepoint_elem): latitude = routepoint.get("lat") longitude = routepoint.get("lon") name = routepoint.findtext(name_elem) description = routepoint.findtext(desc_elem) elevation = routepoint.findtext(elev_elem) if elevation: elevation = float(elevation) time = routepoint.findtext(time_elem) if time: time = utils.Timestamp.parse_isoformat(time) points.append(Routepoint(latitude, longitude, name, description, elevation, time)) self.append(points)
def import_locations(self, kml_file, kml_version=None): """Import KML data files ``import_locations()`` returns a dictionary with keys containing the section title, and values consisting of :class:`Placemark` objects. It expects data files in KML format, as specified in `KML Reference`_, which is XML such as:: <?xml version="1.0" encoding="utf-8"?> <kml xmlns="http://earth.google.com/kml/2.1"> <Document> <Placemark id="Home"> <name>Home</name> <Point> <coordinates>-0.221,52.015,60</coordinates> </Point> </Placemark> <Placemark id="Cambridge"> <name>Cambridge</name> <Point> <coordinates>0.390,52.167</coordinates> </Point> </Placemark> </Document> </kml> The reader uses the :mod:`ElementTree` module, so should be very fast when importing data. The above file processed by ``import_locations()`` will return the following ``dict`` object:: {"Home": Placemark(52.015, -0.221, 60), "Cambridge": Placemark(52.167, 0.390, None)} >>> locations = Placemarks(open("kml")) >>> for value in sorted(locations.values(), ... key=lambda x: x.name.lower()): ... print(value) Cambridge (52°10'01"N, 000°23'24"E) Home (52°00'54"N, 000°13'15"W alt 60m) The ``kml_version`` parameter allows the caller to specify the specific KML version that should be processed, this allows the caller to process inputs which contain entries in more than one namespace without duplicates resulting from entries in being specified with different namespaces. :type kml_file: ``file``, ``list`` or ``str`` :param kml_file: KML data to read :type kml_version: ``str`` :param kml_version: Specific KML version entities to import :rtype: ``dict`` :return: Named locations with optional comments .. _KML Reference: http://code.google.com/apis/kml/documentation/kml_tags_21.html """ self._kml_file = kml_file data = utils.prepare_xml_read(kml_file) if kml_version: try: accepted_kml = {kml_version: KML_VERSIONS[kml_version]} except KeyError: raise KeyError("Unknown KML version `%s'" % kml_version) else: accepted_kml = KML_VERSIONS for version, namespace in accepted_kml.items(): logging.info("Searching for KML v%s entries" % version) kml_elem = lambda name: ET.QName(namespace, name).text placemark_elem = "//" + kml_elem("Placemark") name_elem = kml_elem("name") coords_elem = kml_elem("Point") + "/" + kml_elem("coordinates") desc_elem = kml_elem("description") for place in data.findall(placemark_elem): name = place.findtext(name_elem) coords = place.findtext(coords_elem) if coords is None: logging.info("No coordinates found for `%s' entry" % name) continue coords = coords.split(",") if len(coords) == 2: longitude, latitude = coords altitude = None elif len(coords) == 3: longitude, latitude, altitude = coords else: raise ValueError("Unable to handle coordinates value `%s'" % coords) description = place.findtext(desc_elem) self[name] = Placemark(latitude, longitude, altitude, name, description)
def import_locations(self, gpx_file, gpx_version=None): """Import GPX data files `import_locations()` returns a series of lists representing track segments with `Trackpoint` objects as contents. It expects data files in GPX format, as specified in `GPX 1.1 Schema Documentation <http://www.topografix.com/GPX/1/1/>`__, which is XML such as:: <?xml version="1.0" encoding="utf-8" standalone="no"?> <gpx version="1.1" creator="PocketGPSWorld.com" xmlns="http://www.topografix.com/GPX/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"> <trk> <trkseg> <trkpt lat="52.015" lon="-0.221"> <name>Home</name> <desc>My place</desc> </trkpt> <trkpt lat="52.167" lon="0.390"> <name>MSR</name> <desc>Microsoft Research, Cambridge</desc> </trkpt> </trkseg> </trk> </gpx> The reader uses `Python <http://www.python.org/>`__'s `ElementTree` module, so should be very fast when importing data. The above file processed by `import_locations()` will return the following `list` object:: [[Trackpoint(52.015, -0.221, "Home", "My place"), Trackpoint(52.167, 0.390, "MSR", "Microsoft Research, Cambridge")], ] >>> trackpoints = Trackpoints(open("gpx_tracks")) >>> for value in sorted(trackpoints[0], ... key=lambda x: x.name.lower()): ... print(value) Home (52°00'54"N, 000°13'15"W) [My place] MSR (52°10'01"N, 000°23'24"E) [Microsoft Research, Cambridge] :Parameters: gpx_file : `file`, `list` or `str` GPX data to read gpx_version : `str` Specific GPX version entities to import :rtype: `list` :return: Locations with optional comments """ data = utils.prepare_xml_read(gpx_file) if gpx_version: try: accepted_gpx = {gpx_version: GPX_VERSIONS[gpx_version]} except KeyError: raise KeyError("Unknown GPX version `%s'" % gpx_version) else: accepted_gpx = GPX_VERSIONS for version, namespace in accepted_gpx.items(): logging.info("Searching for GPX v%s entries" % version) gpx_elem = lambda name: ET.QName(namespace, name).text segment_elem = "//" + gpx_elem("trkseg") trackpoint_elem = gpx_elem("trkpt") name_elem = gpx_elem("name") desc_elem = gpx_elem("desc") for segment in data.findall(segment_elem): points = point.Points() for trackpoint in segment.findall(trackpoint_elem): latitude = trackpoint.get("lat") longitude = trackpoint.get("lon") name = trackpoint.findtext(name_elem) description = trackpoint.findtext(desc_elem) points.append( Trackpoint(latitude, longitude, name, description)) self.append(points)
def import_locations(self, kml_file): """Import KML data files. ``import_locations()`` returns a dictionary with keys containing the section title, and values consisting of :class:`Placemark` objects. It expects data files in KML format, as specified in `KML Reference`_, which is XML such as:: <?xml version="1.0" encoding="utf-8"?> <kml xmlns="http://earth.google.com/kml/2.1"> <Document> <Placemark id="Home"> <name>Home</name> <Point> <coordinates>-0.221,52.015,60</coordinates> </Point> </Placemark> <Placemark id="Cambridge"> <name>Cambridge</name> <Point> <coordinates>0.390,52.167</coordinates> </Point> </Placemark> </Document> </kml> The reader uses the :mod:`ElementTree` module, so should be very fast when importing data. The above file processed by ``import_locations()`` will return the following ``dict`` object:: {"Home": Placemark(52.015, -0.221, 60), "Cambridge": Placemark(52.167, 0.390, None)} :type kml_file: ``file``, ``list`` or ``str`` :param kml_file: KML data to read :rtype: ``dict`` :return: Named locations with optional comments .. _KML Reference: http://code.google.com/apis/kml/documentation/kmlreference.html """ self._kml_file = kml_file data = utils.prepare_xml_read(kml_file, objectify=True) for place in data.Document.Placemark: name = place.name.text coords = place.Point.coordinates.text if coords is None: logging.info('No coordinates found for %r entry' % name) continue coords = coords.split(',') if len(coords) == 2: longitude, latitude = coords altitude = None elif len(coords) == 3: longitude, latitude, altitude = coords else: raise ValueError('Unable to handle coordinates value %r' % coords) try: description = place.description except AttributeError: description = None self[name] = Placemark(latitude, longitude, altitude, name, description)
def test_prepare_xml_read(): data = prepare_xml_read(open('tests/data/real_file.xml')) expect(data.find('tag').text) == 'This is a test file-type object' test_list = ['<xml>', '<tag>This is a test list</tag>', '</xml>'] expect(prepare_xml_read(test_list).find('tag').text) == \ 'This is a test list'