Exemplo n.º 1
0
def test_prepare_xml_read(data, result):
    xml = prepare_xml_read(data)
    assert xml.find('tag').text == result
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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))
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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'