Ejemplo n.º 1
0
def format_location_message(x,
                            y,
                            extra_text,
                            html=False,
                            extra=True,
                            osm=True,
                            gmaps=False):
    """Format coordinates of a point into a location message."""
    if osm: osm_url = short_osm(y, x)
    if gmaps: gm = 'http://maps.google.com/?q={y:.5f},{x:.5f}'.format(x=x, y=y)
    plus = olc_encode(y, x)
    if html:
        if extra_text and extra: r = extra_text + '<br>'
        else: r = ''
        r += ('<a href="geo:{y:.5f},{x:.5f}">geo:{y:.5f},{x:.5f}</a>'.format(
            x=x, y=y))
        r += ('<br>{desc}: {plus}'.format(desc=_("plus code"), plus=plus))
        if osm: r += ('<br><a href="{osm}">{osm}</a>'.format(osm=osm_url))
        if gmaps: r += ('<br><a href="{gm}">{gm}</a>'.format(gm=gm))
    else:
        if extra_text and extra: r = extra_text + '; '
        else: r = ''
        r += ('geo:{y:.5f},{x:.5f}'.format(x=x, y=y))
        r += (' {desc}: {plus}'.format(desc=_("plus code"), plus=plus))
        if osm: r += (' {osm}'.format(osm=osm_url))
        if gmaps: r += (' {gm}'.format(gm=gm))
    return r
Ejemplo n.º 2
0
 def _process_route(self, route):
     if "maneuvers" in route:
         mnew = []
         for m in route["maneuvers"]:
             sign = m.get("sign", None)
             street = m.get("street", None)
             if (street is None or len(street) == 0) and sign is not None:
                 if "exit_toward" in sign and sign[
                         "exit_toward"] is not None and len(
                             sign["exit_toward"]) > 0:
                     street = "⇨ " + ("; ".join(sign["exit_toward"]))
                 elif "exit_branch" in sign and sign[
                         "exit_branch"] is not None and len(
                             sign["exit_branch"]) > 0:
                     street = "⇨ " + ("; ".join(sign["exit_branch"]))
                 elif "exit_number" in sign and sign[
                         "exit_number"] is not None and len(
                             sign["exit_number"]) > 0:
                     street = _("Exit: ") + ("; ".join(sign["exit_number"]))
                 elif "exit_name" in sign and sign[
                         "exit_name"] is not None and len(
                             sign["exit_name"]) > 0:
                     street = _("Exit: ") + ("; ".join(sign["exit_name"]))
             elif street is not None and len(street) > 0:
                 street = "; ".join(street)
             mn = copy.deepcopy(m)
             mn["street"] = street
             mnew.append(mn)
         route["maneuvers"] = mnew
Ejemplo n.º 3
0
    def geocode(self, query, params=None, x=0, y=0):
        """
        Return a list of dictionaries of places matching `query`.

        `params` can be used to specify a dictionary of geocoder-specific
        parameters. If the current position as `x` and `y` are provided,
        the results will include correct distance and bearing.
        """
        params = params or {}
        # Parse position if query is a geo URI.
        match = RE_GEO_URI.search(query)
        if match is not None:
            qy, qx = map(float, match.groups())
            return [
                dict(title=_("Point from geo link"),
                     description=match.group(0),
                     x=qx,
                     y=qy,
                     distance=self._format_distance(x, y, qx, qy))
            ]

        try:
            results = self._provider.geocode(query, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Geocoding failed:", file=sys.stderr)
            traceback.print_exc()
            return []
        for result in results:
            result["distance"] = self._format_distance(x, y, result["x"],
                                                       result["y"])
        return results
Ejemplo n.º 4
0
def format_time(seconds):
    """Format `seconds` to format ``# h # min``."""
    seconds = 60 * round(seconds / 60)
    hours = int(seconds / 3600)
    minutes = round((seconds % 3600) / 60)
    if hours == 0:
        return _("{:d} min").format(minutes)
    return _("{:d} h {:d} min").format(hours, minutes)
Ejemplo n.º 5
0
def format_time(seconds):
    """Format `seconds` to format ``# h # min``."""
    seconds = 60 * round(seconds/60)
    hours = int(seconds/3600)
    minutes = round((seconds % 3600) / 60)
    if hours == 0:
        return _("{:d} min").format(minutes)
    return _("{:d} h {:d} min").format(hours, minutes)
Ejemplo n.º 6
0
    def geocode(self, query, params=None, x=0, y=0):
        """
        Return a list of dictionaries of places matching `query`.

        `params` can be used to specify a dictionary of geocoder-specific
        parameters. If the current position as `x` and `y` are provided,
        the results will include correct distance and bearing.
        """
        params = params or {}
        # Parse coordinates if query is a geo URI.
        match = RE_GEO_URI.search(query)
        if match is not None:
            qy = float(match.group(1))
            qx = float(match.group(2))
            return [dict(title=_("Point from geo link"),
                         description=match.group(0),
                         x=qx,
                         y=qy,
                         distance=self._format_distance(x, y, qx, qy),
                         provider=self.id)]

        # Parse coordinates if query is "LAT,LON".
        match = RE_LAT_LON.search(query)
        if match is not None:
            qy = float(match.group(1))
            qx = float(match.group(3))
            return [dict(title=_("Point from coordinates"),
                         description=match.group(0),
                         x=qx,
                         y=qy,
                         distance=self._format_distance(x, y, qx, qy),
                         provider=self.id)]

        # Parse if query is a Plus code
        qtrimmed = query.strip()
        if olc_isFull(qtrimmed):
            latlng = olc_decode(qtrimmed).latlng()
            return [dict(title=qtrimmed.upper(),
                         description=_("Point from Plus code"),
                         x=latlng[1],
                         y=latlng[0],
                         distance=self._format_distance(x, y, latlng[1], latlng[0]),
                         provider=self.id)]

        try:
            results = self._provider.geocode(query, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Geocoding failed:", file=sys.stderr)
            traceback.print_exc()
            return []
        for result in results:
            result["distance"] = self._format_distance(
                x, y, result["x"], result["y"])
            result["provider"] = self.id
        return results
Ejemplo n.º 7
0
def format_distance_metric(meters, n=2, short=True, lang=None):
    """Format `meters` to `n` significant digits and unit label."""
    if meters >= 1000:
        distance = format_decimal(meters / 1000, 0, lang)
        units = _("km") if short else _("kilometers")
        return "{distance} {units}".format(**locals())
    else:
        distance = format_decimal(meters, n, lang)
        units = _("m") if short else _("meters")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 8
0
def format_distance_american(feet, n=2, short=True, lang=None):
    """Format `feet` to `n` significant digits and unit label."""
    if (n > 1 and feet >= 1000) or feet >= 5280:
        distance = format_decimal(feet / 5280, 0, lang)
        units = _("mi") if short else _("miles")
        return "{distance} {units}".format(**locals())
    else:
        distance = format_decimal(feet, n, lang)
        units = _("ft") if short else _("feet")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 9
0
def format_distance_british(yards, n=2, short=True, lang=None):
    """Format `yards` to `n` significant digits and unit label."""
    if (n > 1 and yards >= 400) or yards >= 1760:
        distance = format_decimal(yards / 1760, 0, lang)
        units = _("mi") if short else _("miles")
        return "{distance} {units}".format(**locals())
    else:
        distance = format_decimal(yards, n, lang)
        units = _("yd") if short else _("yards")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 10
0
 def get_display(self, x, y, accuracy=None, navigating=False):
     """Return a dictionary of status details to display."""
     if not self.ready: return None
     if self.mode == "transit":
         return self._get_display_transit(x, y)
     node = self._get_closest_segment_node(x, y)
     seg_dists = self._get_distances_from_route(x, y, node)
     seg_dist = min(seg_dists)
     dest_dist, dest_time = self._get_display_destination(
         x, y, node, seg_dist)
     progress  = (max(self.time) - dest_time) / max(self.time)
     dest_dist = poor.util.format_distance(dest_dist)
     dest_eta = (datetime.datetime.now()+datetime.timedelta(seconds=dest_time)).strftime("%H:%M")
     dest_time = poor.util.format_time(dest_time)
     man = self._get_display_maneuver(x, y, node, seg_dists)
     man_node, man_dist, man_time, icon, narrative, sign, street = man
     if (street is None or len(street)==0) and sign is not None:
         if "exit_toward" in sign and sign["exit_toward"] is not None and len(sign["exit_toward"]) > 0:
             street = ["⇨ " + ("; ".join(sign["exit_toward"]))]
         elif "exit_branch"  in sign and sign["exit_branch"] is not None and len(sign["exit_branch"]) > 0:
             street = ["⇨ " + ("; ".join(sign["exit_branch"]))]
         elif "exit_number"  in sign and sign["exit_number"] is not None and len(sign["exit_number"]) > 0:
             street = [_("Exit: ") + ("; ".join(sign["exit_number"]))]
         elif "exit_name"  in sign and sign["exit_name"] is not None and len(sign["exit_name"]) > 0:
             street = [_("Exit: ") + ("; ".join(sign["exit_name"]))]
     sign = (
         sign if seg_dist < 100 and navigating and (man_dist < 500 or man_time < 300) else None)
     voice_uri = (
         self._get_voice_uri(man_node, man_dist, man_time)
         if seg_dist < 100 and navigating else None)
     man_dist = poor.util.format_distance(man_dist)
     man_time = poor.util.format_time(man_time)
     if seg_dist > 100:
         # Don't show the narrative or details calculated
         # from nodes along the route if far off route.
         dest_time = man_time = icon = narrative = sign = street = None
     # Don't provide route direction to auto-rotate by if off route.
     direction = self._get_direction(x, y, node) if seg_dist < 50 else None
     # Trigger rerouting if off route (usually after missed a turn).
     reroute = seg_dist > 100 + (accuracy or 40000000)
     return dict(total_dist=poor.util.format_distance(max(self.dist)),
                 total_time=poor.util.format_time(max(self.time)),
                 dest_dist=dest_dist,
                 dest_eta=dest_eta,
                 dest_time=dest_time,
                 man_dist=man_dist,
                 man_time=man_time,
                 progress=progress,
                 icon=icon,
                 narrative=narrative,
                 direction=direction,
                 voice_uri=voice_uri,
                 reroute=reroute,
                 sign=sign,
                 street=street)
Ejemplo n.º 11
0
def parse_extras(result):
    """Parse description from geocoding result."""
    description = ""
    with poor.util.silent(Exception):
        t = ", ".join([c.name for c in result.foodTypes])
        description = merge(description, t, categ=_("Food types: {}"))
    with poor.util.silent(Exception):
        t = []
        for i in result.openingHours:
            if "isOpen" not in i or i.isOpen:
                t.extend(i.text)
        t = "; ".join(t)
        description = merge(description, t, categ=_("Opening hours: {}"))
    return description
Ejemplo n.º 12
0
    def nearby(self, query, near, radius, params=None):
        """
        Return a list of dictionaries of places matching `query`.

        `near` can be either a string (usually an address) or a two-element
        tuple or list of (x,y) coordinates. `radius` should be meters around
        `near` to search places for. `params` can be used to specify
        a dictionary of guide-specific parameters.
        """
        params = params or {}
        try:
            x, y, results = self._provider.nearby(query, near, radius, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Nearby failed:", file=sys.stderr)
            traceback.print_exc()
            return []
        for result in results:
            result["distance"] = poor.util.calculate_distance(
                x, y, result["x"], result["y"])
        # Enforce radius in case the provider didn't.
        results = [z for z in results if z["distance"] <= radius]
        for result in results:
            result["distance"] = self._format_distance(
                x, y, result["x"], result["y"])
        return results
Ejemplo n.º 13
0
    def reverse(self, x, y, radius, limit=1, params=None):
        """
        Return a closest object near given coordinates.

        `params` can be used to specify a dictionary of geocoder-specific
        parameters.
        """
        params = params or {}

        try:
            results = self._provider.reverse(x=x,
                                             y=y,
                                             radius=radius,
                                             limit=limit,
                                             params=params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Geocoding failed:", file=sys.stderr)
            traceback.print_exc()
            return []
        results_filtered = []
        for result in results:
            if "distance" not in result:
                result["distance"] = poor.util.calculate_distance(
                    x, y, result["x"], result["y"])
            if result["distance"] < radius:
                result["provider"] = self.id
                results_filtered.append(result)
        return results_filtered
Ejemplo n.º 14
0
    def route(self, locations, params=dict()):
        """Find route and return its properties as a dictionary.

        `locations` is a list of either strings (usually addresses) or
        two-element tuples or lists of (x,y) coordinates. `heading` is
        the initial direction as an angle with zero being north,
        increasing clockwise, with 360 being north again. `heading` is
        mostly useful for rerouting, to avoid suggesting U-turns, and
        will be ``None`` in non-rerouting context. `params` can be
        used to specify a dictionary of router-specific parameters.

        """
        params = AttrDict(params)
        try:
            route = self._provider.route(locations=locations, params=params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Routing failed:", file=sys.stderr)
            traceback.print_exc()
            return {}
        if isinstance(route, dict):
            route["provider"] = self.id
            self._process_route(route)
        if isinstance(route, list):
            for alternative in route:
                if isinstance(alternative, dict):
                    alternative["provider"] = self.id
                    self._process_route(alternative)
        return route
Ejemplo n.º 15
0
    def nearby(self, query, near, radius, params=None):
        """
        Return a list of dictionaries of places matching `query`.

        `near` can be either a string (usually an address) or a two-element
        tuple or list of (x,y) coordinates. `radius` should be meters around
        `near` to search places for. `params` can be used to specify
        a dictionary of guide-specific parameters.
        """
        params = params or {}
        try:
            x, y, results = self._provider.nearby(query, near, radius, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Nearby failed:", file=sys.stderr)
            traceback.print_exc()
            return []
        for result in results:
            if "distance" not in result:
                result["distance"] = poor.util.calculate_distance(
                    x, y, result["x"], result["y"])
            result["provider"] = self.id
        for result in results:
            result["distance"] = self._format_distance(
                x, y, result["x"], result["y"], result["distance"])
        return results
Ejemplo n.º 16
0
def parse_text(venue):
    """Parse blurb text from venue details."""
    lines = []
    subtitle = []
    with poor.util.silent(Exception):
        subtitle.append(('{:.1f} / 10').format(venue.rating))
    lines.append("  ".join(subtitle))
    with poor.util.silent(Exception):
        tip = parse_tip(venue) or venue.get("description") or ""
        if not tip: raise ValueError("No tip")
        lines.append("{}".format(tip))
        lines.append("")
    with poor.util.silent(Exception):
        hours = venue.hours
        open_lines = []
        for i in hours.timeframes:
            s = i.days + ": "
            for j in i.open:
                s += j.renderedTime + " "
            open_lines.append(s.strip())
        if len(open_lines) > 0:
            lines.append(_("Opening hours:"))
            lines.extend(open_lines)
        lines.append("")
    with poor.util.silent(Exception):
        for i in venue.attributes.groups:
            for j in i['items']:
                if j.displayName != j.displayValue:
                    lines.append("{}: {}".format(j.displayName,
                                                 j.displayValue))
                else:
                    lines.append(j.displayName)
    return "\n".join(lines)
Ejemplo n.º 17
0
def format_distance_metric(meters, n=2, short=True):
    """Format `meters` to `n` significant digits and unit label."""
    if meters >= 1000:
        distance = meters / 1000
        ndigits = n - get_ndigits(distance)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("km") if short else _("kilometers")
        return "{distance} {units}".format(**locals())
    else:
        distance = meters
        ndigits = n - get_ndigits(distance)
        ndigits = min(0, ndigits)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("m") if short else _("meters")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 18
0
def format_distance_american(feet, n=2, short=True):
    """Format `feet` to `n` significant digits and unit label."""
    if (n > 1 and feet >= 1000) or feet >= 5280:
        distance = feet / 5280
        ndigits = n - get_ndigits(distance)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("mi") if short else _("miles")
        return "{distance} {units}".format(**locals())
    else:
        distance = feet
        ndigits = n - get_ndigits(distance)
        ndigits = min(0, ndigits)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("ft") if short else _("feet")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 19
0
def format_distance_british(yards, n=2, short=True):
    """Format `yards` to `n` significant digits and unit label."""
    if (n > 1 and yards >= 400) or yards >= 1760:
        distance = yards / 1760
        ndigits = n - get_ndigits(distance)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("mi") if short else _("miles")
        return "{distance} {units}".format(**locals())
    else:
        distance = yards
        ndigits = n - get_ndigits(distance)
        ndigits = min(0, ndigits)
        distance = round(distance, ndigits)
        distance = "{{:.{:d}f}}".format(max(0, ndigits)).format(distance)
        units = _("yd") if short else _("yards")
        return "{distance} {units}".format(**locals())
Ejemplo n.º 20
0
def format_distance_british(yards, n=2, short=True):
    """Format `yards` to `n` significant digits and unit label."""
    if (n > 1 and yards >= 400) or yards >= 1760:
        distance = yards / 1760
        units = "mi"
    else:
        # Let's not use units less than a yard.
        distance = yards
        units = "yd"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1/1000000))
    if units == "yd":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^mi$", _("miles"), units)
        units = re.sub("^yd$", _("yards"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 21
0
def format_distance_metric(meters, n=2, short=True):
    """Format `meters` to `n` significant digits and unit label."""
    if meters >= 1000:
        distance = meters / 1000
        units = "km"
    else:
        # Let's not use units less than a meter.
        distance = meters
        units = "m"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1/1000000))
    if units == "m":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^m$", _("meters"), units)
        units = re.sub("^km$", _("kilometers"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 22
0
def format_distance_american(feet, n=2, short=True):
    """Format `feet` to `n` significant digits and unit label."""
    if (n > 1 and feet >= 1000) or feet >= 5280:
        distance = feet / 5280
        units = "mi"
    else:
        # Let's not use units less than a foot.
        distance = feet
        units = "ft"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1/1000000))
    if units == "ft":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^mi$", _("miles"), units)
        units = re.sub("^ft$", _("feet"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 23
0
def format_distance_metric(meters, n=2, short=True):
    """Format `meters` to `n` significant digits and unit label."""
    if meters >= 1000:
        distance = meters / 1000
        units = "km"
    else:
        # Let's not use units less than a meter.
        distance = meters
        units = "m"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1 / 1000000))
    if units == "m":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^m$", _("meters"), units)
        units = re.sub("^km$", _("kilometers"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 24
0
def format_distance_american(feet, n=2, short=True):
    """Format `feet` to `n` significant digits and unit label."""
    if (n > 1 and feet >= 1000) or feet >= 5280:
        distance = feet / 5280
        units = "mi"
    else:
        # Let's not use units less than a foot.
        distance = feet
        units = "ft"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1 / 1000000))
    if units == "ft":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^mi$", _("miles"), units)
        units = re.sub("^ft$", _("feet"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 25
0
def format_distance_british(yards, n=2, short=True):
    """Format `yards` to `n` significant digits and unit label."""
    if (n > 1 and yards >= 400) or yards >= 1760:
        distance = yards / 1760
        units = "mi"
    else:
        # Let's not use units less than a yard.
        distance = yards
        units = "yd"
    ndigits = n - math.ceil(math.log10(abs(max(1, distance)) + 1 / 1000000))
    if units == "yd":
        ndigits = min(0, ndigits)
    distance = round(distance, ndigits)
    if not short:
        units = re.sub("^mi$", _("miles"), units)
        units = re.sub("^yd$", _("yards"), units)
    fstring = "{{:.{:d}f}} {{}}".format(max(0, ndigits))
    return fstring.format(distance, units)
Ejemplo n.º 26
0
def format_distance_and_bearing(meters, bearing, n=2, short=True):
    """Format `meters` and `bearing` to a human readable string."""
    distance = format_distance(meters, n, short)
    f = lambda x: x.format(distance=distance)
    bearing = (bearing + 360) % 360
    bearing = int(round(bearing/45) * 45)
    if bearing ==   0: return f(_("{distance} north"))
    if bearing ==  45: return f(_("{distance} north-east"))
    if bearing ==  90: return f(_("{distance} east"))
    if bearing == 135: return f(_("{distance} south-east"))
    if bearing == 180: return f(_("{distance} south"))
    if bearing == 225: return f(_("{distance} south-west"))
    if bearing == 270: return f(_("{distance} west"))
    if bearing == 315: return f(_("{distance} north-west"))
    if bearing == 360: return f(_("{distance} north"))
    raise ValueError("Unexpected bearing: {}".format(repr(bearing)))
Ejemplo n.º 27
0
def format_distance_and_bearing(meters, bearing, n=2, short=True):
    """Format `meters` and `bearing` to a human readable string."""
    distance = format_distance(meters, n, short)
    f = lambda x: x.format(distance=distance)
    bearing = (bearing + 360) % 360
    bearing = int(round(bearing / 45) * 45)
    if bearing == 0: return f(_("{distance} north"))
    if bearing == 45: return f(_("{distance} north-east"))
    if bearing == 90: return f(_("{distance} east"))
    if bearing == 135: return f(_("{distance} south-east"))
    if bearing == 180: return f(_("{distance} south"))
    if bearing == 225: return f(_("{distance} south-west"))
    if bearing == 270: return f(_("{distance} west"))
    if bearing == 315: return f(_("{distance} north-west"))
    if bearing == 360: return f(_("{distance} north"))
    raise ValueError("Unexpected bearing: {}".format(repr(bearing)))
Ejemplo n.º 28
0
    def route(self, fm, to, params=None):
        """
        Find route and return its properties as a dictionary.

        `fm` and `to` can be either strings (usually addresses) or two-element
        tuples or lists of (x,y) coordinates. `params` can be used to specify
        a dictionary of router-specific parameters.
        """
        params = params or {}
        try:
            return self._provider.route(fm, to, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Routing failed:", file=sys.stderr)
            traceback.print_exc()
            return {}
Ejemplo n.º 29
0
def parse_maneuvers(route):
    """Parse list of maneuvers from the legs of `route`."""
    if not route.legs: return []
    maneuvers = []
    prev_mode = "w"
    modes = dict(WALK="w", BICYCLE="b")
    for i, leg in enumerate(route.legs):
        this_mode = modes.get(leg.mode, "t")
        key = prev_mode + this_mode
        # Handle the last leg differently since OpenTripPlanner
        # gives "Destination" as the destination name.
        if i == len(route.legs) - 1:
            key = key[0] + "a"
        narrative = NARRATIVE[key].format(**leg)
        narrative = re.sub(r"\.\.+$", ".", narrative)
        maneuvers.append(
            poor.AttrDict(x=leg.dep_x,
                          y=leg.dep_y,
                          icon="flag",
                          narrative=narrative,
                          duration=leg.duration))
        if this_mode == "t":
            # Add intermediate stops as passive maneuver points.
            maneuvers.extend([
                poor.AttrDict(
                    x=leg.stops_x[i],
                    y=leg.stops_y[i],
                    passive=True,
                ) for i in range(len(leg.stops_x))
            ])
        prev_mode = this_mode
    maneuvers.append(
        poor.AttrDict(x=route.legs[-1].arr_x,
                      y=route.legs[-1].arr_y,
                      icon="flag",
                      narrative=_("Arrive at your destination."),
                      duration=0))
    # For clarity, move stops to the nearest point
    # on the route polyline.
    for maneuver in maneuvers:
        i = poor.util.find_closest(route.x, route.y, maneuver.x, maneuver.y)
        maneuver.x = route.x[i]
        maneuver.y = route.y[i]
    return maneuvers
Ejemplo n.º 30
0
def parse_maneuvers(route):
    """Parse list of maneuvers from the legs of `route`."""
    if not route.legs: return []
    maneuvers = []
    prev_mode = "w"
    modes = dict(WALK="w", BICYCLE="b")
    for i, leg in enumerate(route.legs):
        this_mode = modes.get(leg.mode, "t")
        key = prev_mode + this_mode
        # Handle the last leg differently since OpenTripPlanner
        # gives "Destination" as the destination name.
        if i == len(route.legs) - 1:
            key = key[0] + "a"
        narrative = NARRATIVE[key].format(**leg)
        narrative = re.sub(r"\.\.+$", ".", narrative)
        maneuvers.append(poor.AttrDict(
            x=leg.dep_x,
            y=leg.dep_y,
            icon="flag",
            narrative=narrative,
            duration=leg.duration))
        if this_mode == "t":
            # Add intermediate stops as passive maneuver points.
            maneuvers.extend([poor.AttrDict(
                x=leg.stops_x[i],
                y=leg.stops_y[i],
                passive=True,
            ) for i in range(len(leg.stops_x))])
        prev_mode = this_mode
    maneuvers.append(poor.AttrDict(
        x=route.legs[-1].arr_x,
        y=route.legs[-1].arr_y,
        icon="flag",
        narrative=_("Arrive at your destination."),
        duration=0))
    # For clarity, move stops to the nearest point
    # on the route polyline.
    for maneuver in maneuvers:
        i = poor.util.find_closest(route.x, route.y, maneuver.x, maneuver.y)
        maneuver.x = route.x[i]
        maneuver.y = route.y[i]
    return maneuvers
Ejemplo n.º 31
0
    def route(self, fm, to, heading=None, params=None):
        """Find route and return its properties as a dictionary.

        `fm` and `to` can be either strings (usually addresses) or two-element
        tuples or lists of (x,y) coordinates. `heading` is the initial
        direction as an angle with zero being north, increasing clockwise, with
        360 being north again. `heading` is mostly useful for rerouting, to
        avoid suggesting U-turns, and will be ``None`` in non-rerouting
        context. `params` can be used to specify a dictionary of
        router-specific parameters.
        """
        params = params or {}
        try:
            return self._provider.route(fm, to, heading, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Routing failed:", file=sys.stderr)
            traceback.print_exc()
            return {}
Ejemplo n.º 32
0
    def route(self, fm, to, heading=None, params=None):
        """Find route and return its properties as a dictionary.

        `fm` and `to` can be either strings (usually addresses) or two-element
        tuples or lists of (x,y) coordinates. `heading` is the initial
        direction as an angle with zero being north, increasing clockwise, with
        360 being north again. `heading` is mostly useful for rerouting, to
        avoid suggesting U-turns, and will be ``None`` in non-rerouting
        context. `params` can be used to specify a dictionary of
        router-specific parameters.
        """
        params = params or {}
        try:
            return self._provider.route(fm, to, heading, params)
        except socket.timeout:
            return dict(error=True, message=_("Connection timed out"))
        except Exception:
            print("Routing failed:", file=sys.stderr)
            traceback.print_exc()
            return {}
Ejemplo n.º 33
0
class HistoryManager:
    """Managing a history of search queries."""

    _places_blacklist = ["Current position", _("Current position")]

    def __init__(self):
        """Initialize a :class:`HistoryManager` instance."""
        self._path = os.path.join(poor.CONFIG_HOME_DIR, "search-history.json")
        self._place_names = []
        self._place_types = []
        self._places = []
        self._read()

    def add_place(self, place):
        """Add `place` to the list of places."""
        place = place.strip()
        if not place: return
        if place in self._places_blacklist: return
        self.remove_place(place)
        self._places.insert(0, place)

    def add_place_name(self, place_name):
        """Add `place_name` to the list of place names."""
        place_name = place_name.strip()
        if not place_name: return
        self.remove_place_name(place_name)
        self._place_names.insert(0, place_name)

    def add_place_type(self, place_type):
        """Add `place_type` to the list of place types."""
        place_type = place_type.strip()
        if not place_type: return
        self.remove_place_type(place_type)
        self._place_types.insert(0, place_type)

    @property
    def place_names(self):
        """Return a list of place names."""
        return self._place_names[:]

    @property
    def place_types(self):
        """Return a list of place types."""
        return self._place_types[:]

    @property
    def places(self):
        """Return a list of places."""
        return self._places[:]

    def _read(self):
        """Read list of queries from file."""
        with poor.util.silent(Exception, tb=True):
            if os.path.isfile(self._path):
                history = poor.util.read_json(self._path)
                self._places = history.get("places", [])
                self._place_names = history.get("place_names", [])
                self._place_types = history.get("place_types", [])
        for place in self._places_blacklist:
            self.remove_place(place)
        if not self._place_types:
            # Provide some examples of place types.
            self._place_types = [
                "ATM", "Café", "Gas station", "Grocery store", "Hotel", "Pub",
                "Restaurant"
            ]

    def remove_place(self, place):
        """Remove `place` from the list of places."""
        place = place.strip().lower()
        for i in reversed(range(len(self._places))):
            if self._places[i].lower() == place:
                del self._places[i]

    def remove_place_name(self, place_name):
        """Remove `place_name` from the list of place names."""
        place_name = place_name.strip().lower()
        for i in reversed(range(len(self._place_names))):
            if self._place_names[i].lower() == place_name:
                del self._place_names[i]

    def remove_place_type(self, place_type):
        """Remove `place_type` from the list of place types."""
        place_type = place_type.strip().lower()
        for i in reversed(range(len(self._place_types))):
            if self._place_types[i].lower() == place_type:
                del self._place_types[i]

    def write(self):
        """Write list of queries to file."""
        with poor.util.silent(Exception, tb=True):
            poor.util.write_json(
                {
                    "places": self._places[:1000],
                    "place_names": self._place_names[:1000],
                    "place_types": self._place_types[:1000],
                }, self._path)
Ejemplo n.º 34
0
def get_routing_attribution(service, engine=None):
    """Return translated routing attribution string."""
    if engine is None:
        return _("Routing courtesy of {}.").format(service)
    return (_("Routing by {engine}, courtesy of {service}.")
            .format(engine=engine, service=service))
Ejemplo n.º 35
0
    # maptiler.com
    "MAPTILER_KEY",

    # http://open.mapquestapi.com
    "MAPQUEST_KEY",

    # https://geocoder.opencagedata.com/api
    "OPENCAGE_KEY",

    # https://docs.stadiamaps.com/
    "STADIAMAPS_KEY"
]

HEADERS = {
    "FOURSQUARE": HeaderDesc(_('Register at <a href="https://developer.foursquare.com">https://developer.foursquare.com</a> and create your own Client ID and Client Secret keys'), "Foursquare"),
    "MAPBOX": HeaderDesc(_('Register at <a href="https://www.mapbox.com">https://www.mapbox.com</a> and create your own API key'), "Mapbox"),
    "MAPTILER": HeaderDesc(_('Register at <a href="https://maptiler.com">https://maptiler.com</a> and create your own API key'), "MapTiler"),
    "MAPQUEST": HeaderDesc(_('Register at <a href="https://developer.mapquest.com">https://developer.mapquest.com</a> and create your own API key'), "MapQuest"),
    "OPENCAGE": HeaderDesc(_('Register at <a href="https://opencagedata.com">https://opencagedata.com</a> and create your own API key'), "OpenCage"),
    "STADIAMAPS": HeaderDesc(_('Register at <a href="https://stadiamaps.com">https://stadiamaps.com</a> and create your own API key'), "Stadia Maps"),
    "HERE": HeaderDesc(_('Register at <a href="https://developer.here.com">https://developer.here.com</a> and create your own App API Key'), "HERE")
}

KEYDESC = {
    "FOURSQUARE_CLIENT": _("Foursquare Client ID"),
    "FOURSQUARE_SECRET": _("Foursquare Client Secret"),

    # mapbox.com
    "MAPBOX_KEY": _("Mapbox API key"),
Ejemplo n.º 36
0
 def translate(value):
     if isinstance(value, list):
         return list(map(translate, value))
     return _(value)
Ejemplo n.º 37
0
class HistoryManager:
    """Managing a history of search queries and destinations."""

    _places_blacklist = ["Current position", _("Current position")]

    def __init__(self):
        """Initialize a :class:`HistoryManager` instance."""
        self._destinations = []
        self._path = os.path.join(poor.CONFIG_HOME_DIR, "search-history.json")
        self._place_names = []
        self._place_types = []
        self._places = []
        self._routes = []
        self._read()

    def add_destination(self, dest):
        """Add `dest` to the history list of destinations."""
        d = {'text': dest['text'].strip(), 'x': dest['x'], 'y': dest['y']}
        if not d['text']: return
        self.remove_destination(d['text'])
        self._destinations.insert(0, d)

    def add_place(self, place):
        """Add `place` to the list of places."""
        place = place.strip()
        if not place: return
        if place in self._places_blacklist: return
        self.remove_place(place)
        self._places.insert(0, place)

    def add_place_name(self, place_name):
        """Add `place_name` to the list of place names."""
        place_name = place_name.strip()
        if not place_name: return
        self.remove_place_name(place_name)
        self._place_names.insert(0, place_name)

    def add_place_type(self, place_type):
        """Add `place_type` to the list of place types."""
        place_type = place_type.strip()
        if not place_type: return
        self.remove_place_type(place_type)
        self._place_types.insert(0, place_type)

    def add_route(self, route):
        """Add `route` to the list of routes."""
        route = AttrDict(route)
        for r in route.locations:
            r['text'] = r['text'].strip()
        if len(route.locations) < 2 or not route.locations[0][
                'text'] or not route.locations[-1]['text']:
            return
        self.remove_route(route)
        self._routes.insert(0, route)

    def clear(self):
        """Clear all history"""
        self._destinations = []
        self._place_names = []
        self._place_types = []
        self._places = []
        self._routes = []
        self.write()

    @property
    def destinations(self):
        """Return a list of destinations."""
        return self._destinations[:]

    @property
    def place_names(self):
        """Return a list of place names."""
        return self._place_names[:]

    @property
    def place_types(self):
        """Return a list of place types."""
        return self._place_types[:]

    @property
    def places(self):
        """Return a list of places."""
        return self._places[:]

    def _read(self):
        """Read list of queries, destinations, and routes from file."""
        with poor.util.silent(Exception, tb=True):
            if os.path.isfile(self._path):
                history = poor.util.read_json(self._path)
                self._destinations = history.get("destinations", [])
                self._places = history.get("places", [])
                self._place_names = history.get("place_names", [])
                self._place_types = history.get("place_types", [])
                self._routes = history.get("routes", [])
        for place in self._places_blacklist:
            self.remove_place(place)
        if not self._place_types:
            # Provide some examples of place types.
            self._place_types = [
                "ATM", "Café", "Gas station", "Grocery store", "Hotel", "Pub",
                "Restaurant"
            ]
        # convert old routes format to the new one
        for i in range(len(self._routes)):
            if isinstance(self._routes[i], dict) and "from" in self._routes[i]:
                # old format, pre 2.2
                r = self._routes[i]
                self._routes[i] = dict(locations=[r['from'], r['to']],
                                       optimized=False)
            elif isinstance(self._routes[i], list):
                # old format, 2.2
                self._routes[i] = dict(locations=self._routes[i],
                                       optimized=False)
            self._routes[i] = AttrDict(self._routes[i])

    @property
    def routes(self):
        """Return a list of routes."""
        return self._routes[:]

    def remove_destination(self, dtxt):
        """Remove destination with the text `dtxt` from the list of destinations."""
        t = dtxt.strip()
        for i in reversed(range(len(self._destinations))):
            if self._destinations[i]['text'] == t:
                del self._destinations[i]

    def remove_place(self, place):
        """Remove `place` from the list of places."""
        place = place.strip().lower()
        for i in reversed(range(len(self._places))):
            if self._places[i].lower() == place:
                del self._places[i]

    def remove_place_name(self, place_name):
        """Remove `place_name` from the list of place names."""
        place_name = place_name.strip().lower()
        for i in reversed(range(len(self._place_names))):
            if self._place_names[i].lower() == place_name:
                del self._place_names[i]

    def remove_place_type(self, place_type):
        """Remove `place_type` from the list of place types."""
        place_type = place_type.strip().lower()
        for i in reversed(range(len(self._place_types))):
            if self._place_types[i].lower() == place_type:
                del self._place_types[i]

    def remove_route(self, route):
        """Remove route with the same text for origin and target from the list of routes."""
        def rkey(route):
            return ' - '.join([r['text'] for r in route.locations
                               ]) + ('#opt' if route.optimized else '#no')

        if isinstance(route, dict):
            route = AttrDict(route)
        key = rkey(route)
        for i in reversed(range(len(self._routes))):
            if rkey(self._routes[i]) == key:
                del self._routes[i]

    def write(self):
        """Write list of queries to file."""
        with poor.util.silent(Exception, tb=True):
            poor.util.write_json(
                {
                    "destinations": self._destinations[:25],
                    "places": self._places[:1000],
                    "place_names": self._place_names[:1000],
                    "place_types": self._place_types[:1000],
                    "routes": self._routes[:25]
                }, self._path)
Ejemplo n.º 38
0
 def translate(value):
     if isinstance(value, list):
         return list(map(translate, value))
     return _(value)
Ejemplo n.º 39
0
def get_routing_attribution(service, engine=None):
    """Return translated routing attribution string."""
    if engine is None:
        return _("Routing courtesy of {}.").format(service)
    return (_("Routing by {engine}, courtesy of {service}.").format(
        engine=engine, service=service))
Ejemplo n.º 40
0
   "SUBWAY": "#ff6319",
     "TRAM": "#00985f",
     "WALK": "#888888",
}

CONF_DEFAULTS = {
    # See digitransit_settings.qml for all possible values.
    "modes": ["AIRPLANE", "BUS", "FERRY", "RAIL", "SUBWAY", "TRAM", "WALK"],
    "optimize": "default",
    "region": "hsl",
}

HEADERS = {"Content-Type": "application/graphql"}

MODE_NAMES = {
 "AIRPLANE": _("airplane"),
  "BICYCLE": _("bicycle"),
      "BUS": _("bus"),
    "FERRY": _("ferry"),
     "RAIL": _("train"),
   "SUBWAY": _("metro"),
     "TRAM": _("tram"),
     "WALK": _("walk"),
}

NARRATIVE = {
    "ww": _("Walk towards {arr_name}."),
    "wb": _("Get a city bike at {dep_name}."),
    "wt": _("Board {mode_name} {line_desc} at {dep_name} at {dep_time}."),
    "wa": _("Walk towards your destination."),
    "bw": _("Leave the city bike at {dep_name} and walk towards {arr_name}."),
Ejemplo n.º 41
0
    "SUBWAY": "#ff6319",
    "TRAM": "#00985f",
    "WALK": "#888888",
}

CONF_DEFAULTS = {
    # See digitransit_settings.qml for all possible values.
    "modes": ["AIRPLANE", "BUS", "FERRY", "RAIL", "SUBWAY", "TRAM", "WALK"],
    "optimize": "default",
    "region": "hsl",
}

HEADERS = {"Content-Type": "application/graphql"}

MODE_NAMES = {
    "AIRPLANE": _("airplane"),
    "BICYCLE": _("bicycle"),
    "BUS": _("bus"),
    "FERRY": _("ferry"),
    "RAIL": _("train"),
    "SUBWAY": _("metro"),
    "TRAM": _("tram"),
    "WALK": _("walk"),
}

NARRATIVE = {
    "ww":
    _("Walk towards {arr_name}."),
    "wb":
    _("Get a city bike at {dep_name}."),
    "wt":