Пример #1
0
def nearby(query, near, radius, params):
    """Return X, Y and a list of dictionaries of places matching `query`."""
    query = urllib.parse.quote_plus(query)
    sort_by_distance = str(int(poor.conf.guides.foursquare.sort_by_distance))
    x, y = prepare_point(near)
    url = EXPLORE_URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    results = poor.http.get_json(url)
    results = poor.AttrDict(results)
    results = [
        poor.AttrDict(
            id=item.venue.id,
            title=item.venue.name,
            description=parse_description(item.venue),
            text=parse_text(item.venue),
            link=get_link(item.venue.id),
            x=float(item.venue.location.lng),
            y=float(item.venue.location.lat),
        ) for item in itertools.chain.from_iterable(
            group["items"] for group in results.response.get("groups", []))
    ]
    with poor.util.silent(Exception, tb=True):
        inject_venue_details(results)
    if results and results[0]:
        cache[url] = copy.deepcopy((x, y, results))
    return x, y, results
Пример #2
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    if heading is not None:
        fm["heading"] = heading
    lang = poor.util.get_default_language("en")
    input = dict(locations=[fm, to],
                 costing=poor.conf.routers.mapzen.type,
                 directions_options=dict(language=lang))

    input = urllib.parse.quote(json.dumps(input))
    url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    legs = result.trip.legs[0]
    x, y = poor.util.decode_epl(legs.shape, precision=6)
    maneuvers = [
        dict(
            x=float(x[maneuver.begin_shape_index]),
            y=float(y[maneuver.begin_shape_index]),
            icon=ICONS.get(maneuver.type, "flag"),
            narrative=maneuver.instruction,
            duration=float(maneuver.time),
        ) for maneuver in legs.maneuvers
    ]
    route = dict(x=x, y=y, maneuvers=maneuvers, mode="car")
    route["attribution"] = poor.util.get_routing_attribution("Mapzen")
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #3
0
def route(locations, params):
    """Find route and return its properties as a dictionary."""
    loc = list(map(prepare_endpoint, locations))
    heading = params.get('heading', None)
    optimized = params.get('optimized', False) if len(loc) > 3 else False
    if heading is not None:
        loc[0]["heading"] = heading
    language = poor.conf.routers.stadiamaps.language
    units = "kilometers" if poor.conf.units == "metric" else "miles"
    ctype = poor.conf.routers.stadiamaps.type
    if ctype == "auto" and poor.conf.routers.stadiamaps.shorter:
        ctype = "auto_shorter"
    co = {key: poor.conf.routers.stadiamaps[key] for key in MODEOPTIONS[ctype]}
    costing_options = {}
    costing_options[ctype] = co
    input = dict(locations=loc,
                 costing=ctype,
                 costing_options=costing_options,
                 directions_options=dict(language=language, units=units))

    input = urllib.parse.quote(json.dumps(input))
    if optimized:
        url = URL_OPT.format(**locals())
    else:
        url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    mode = MODE.get(ctype, "car")
    return parse_result_valhalla(url, locations, optimized, result, mode)
Пример #4
0
def parse_legs(legs):
    """Parse legs from routing result."""
    legs = [
        poor.AttrDict(
            mode=leg.mode,
            mode_name=MODE_NAMES.get(leg.mode, "BUS"),
            color=COLORS.get(leg.mode, "BUS"),
            agency=parse_agency(leg),
            line=parse_line(leg),
            line_desc=parse_line_description(leg),
            length=float(leg.distance),
            duration=float(leg.duration),
            real_time=leg.realTime,
            dep_name=leg["from"].name,
            dep_x=float(leg["from"].lon),
            dep_y=float(leg["from"].lat),
            dep_time=parse_time(leg.startTime),
            dep_unix=float(leg.startTime) / 1000,
            arr_name=leg.to.name,
            arr_x=float(leg.to.lon),
            arr_y=float(leg.to.lat),
            arr_time=parse_time(leg.endTime),
            arr_unix=float(leg.endTime) / 1000,
            x=poor.util.decode_epl(leg.legGeometry.points, precision=5)[0],
            y=poor.util.decode_epl(leg.legGeometry.points, precision=5)[1],
            stops_x=[float(x.lon) for x in leg.intermediateStops or []],
            stops_y=[float(x.lat) for x in leg.intermediateStops or []],
        ) for leg in legs
    ]
    merge_bad_legs(legs)
    return legs
Пример #5
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    if heading is not None:
        fm["heading"] = heading
    language = poor.conf.routers.osmscout.language
    units = "kilometers" if poor.conf.units == "metric" else "miles"
    ctype = poor.conf.routers.osmscout.type
    if ctype == "auto" and poor.conf.routers.osmscout.shorter: ctype = "auto_shorter"
    co = {key: poor.conf.routers.osmscout[key] for key in MODEOPTIONS[ctype]}
    costing_options = {}
    costing_options[ctype] = co
    input = dict(locations=[fm, to],
                 costing=ctype,
                 costing_options=costing_options,
                 directions_options=dict(language=language, units=units))

    input = urllib.parse.quote(json.dumps(input))
    url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    mode = MODE.get(ctype,"car")
    if result.get("API version", "") == "libosmscout V1":
        return parse_result_libosmscout(url, result, mode)
    return parse_result_valhalla(url, result, mode)
Пример #6
0
 def make(self, text, preserve=False):
     """Queue `text` for WAV file generation."""
     if self._engine is None: return
     self._update_cache()
     self._used_counter += 1
     if text in self._cache:
         # WAV file already generated, just update
         # file modification time to prevent removal.
         if self._cache[text] is not None:
             self._cache[text].used = self._used_counter
         return
     if self._worker_thread is None:
         self._result_queue = queue.Queue()
         self._task_queue = queue.Queue()
         self._worker_thread = threading.Thread(
             target=voice_worker,
             kwargs=dict(task_queue=self._task_queue,
                         result_queue=self._result_queue,
                         engine=self._engine,
                         tmpdir=self._tmpdir),
             daemon=True)
         self._worker_thread.start()
     # Add an empty element into cache to ensure that we don't
     # run the same voice direction twice through the engine.
     self._cache[text] = poor.AttrDict(fname=None,
                                       preserve=preserve,
                                       text=text,
                                       used=self._used_counter)
     self._task_queue.put(text)
     self._clean_outdated_cache()
Пример #7
0
def nearby(query, near, radius, params):
    """Return X, Y and a list of dictionaries of places matching `query`."""
    query = urllib.parse.quote_plus(query)
    limit = params.get("limit", 50)
    if isinstance(near, (list, tuple)):
        x, y = near[0], near[1]
        url = URL_XY.format(**locals())
    else:
        search = urllib.parse.quote_plus(near)
        url = URL_SEARCH.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    results = poor.http.get_json(url)
    results = poor.AttrDict(results)
    x = float(results.origin.lng)
    y = float(results.origin.lat)
    results = [dict(
        title=result.title,
        description=parse_description(result),
        x=float(result.lng),
        y=float(result.lat),
    ) for result in results.results]
    if results and results[0]:
        results = poor.util.sorted_by_distance(results, x, y)
        cache[url] = copy.deepcopy((x, y, results))
    return x, y, results
Пример #8
0
def reverse(x, y, radius, limit=25, params={}):
    """Return a list of dictionaries of places nearby given coordinates."""
    lng = x
    lat = y
    url = URL_REVERSE.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    results = poor.http.get_json(url)
    results = poor.AttrDict(results)
    results = [
        dict(
            address=parse_address(result),
            link=result.get("website", ""),
            phone=result.get("phone", ""),
            poi_type=parse_type(result),
            postcode=result.get("postal_code", ""),
            title=result.title,
            description=parse_description(result),
            distance=float(result.distance),
            x=float(result.lng),
            y=float(result.lat),
        ) for result in results.results
    ]
    if results and results[0]:
        cache[url] = copy.deepcopy(results)
    return results
Пример #9
0
 def get_recursive(item, level=1):
     children = item.get("categories", [])
     children = list(
         itertools.chain.from_iterable(
             get_recursive(x, level=level + 1) for x in children))
     return [
         poor.AttrDict(
             id=item.get("id"), label=item.get("name"), level=level)
     ] + children
Пример #10
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
Пример #11
0
 def _split_option(self, option, create=False):
     """Split dotted option to dictionary and option name."""
     root = self
     for section in option.split(".")[:-1]:
         if create and section not in root:
             # Create missing hierarchies.
             root[section] = poor.AttrDict()
         root = root[section]
     name = option.split(".")[-1]
     return root, name
Пример #12
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    if heading is not None:
        fm["heading"] = heading
    language = poor.conf.routers.stadiamaps.language
    units = "kilometers" if poor.conf.units == "metric" else "miles"
    ctype = poor.conf.routers.stadiamaps.type
    if ctype == "auto" and poor.conf.routers.stadiamaps.shorter:
        ctype = "auto_shorter"
    co = {key: poor.conf.routers.stadiamaps[key] for key in MODEOPTIONS[ctype]}
    costing_options = {}
    costing_options[ctype] = co
    input = dict(locations=[fm, to],
                 costing=ctype,
                 costing_options=costing_options,
                 directions_options=dict(language=language, units=units))

    input = urllib.parse.quote(json.dumps(input))
    url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    legs = result.trip.legs[0]
    x, y = poor.util.decode_epl(legs.shape, precision=6)
    maneuvers = [
        dict(
            x=float(x[maneuver.begin_shape_index]),
            y=float(y[maneuver.begin_shape_index]),
            icon=ICONS.get(maneuver.type, "flag"),
            narrative=maneuver.instruction,
            sign=dict(exit_branch=parse_exit(maneuver, "exit_branch_elements"),
                      exit_name=parse_exit(maneuver, "exit_name_elements"),
                      exit_number=parse_exit(maneuver, "exit_number_elements"),
                      exit_toward=parse_exit(maneuver,
                                             "exit_toward_elements")),
            street=maneuver.get("begin_street_names",
                                maneuver.get("street_names", None)),
            arrive_instruction=maneuver.get("arrive_instruction", None),
            depart_instruction=maneuver.get("depart_instruction", None),
            travel_type=maneuver.get("travel_type", None),
            verbal_alert=maneuver.get("verbal_transition_alert_instruction",
                                      None),
            verbal_pre=maneuver.get("verbal_pre_transition_instruction", None),
            verbal_post=maneuver.get("verbal_post_transition_instruction",
                                     None),
            duration=float(maneuver.time),
        ) for maneuver in legs.maneuvers
    ]
    route = dict(x=x, y=y, maneuvers=maneuvers, mode=MODE.get(ctype, "car"))
    route["language"] = result.trip.language
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #13
0
def get_types():
    """Return a list of available venue types."""
    results = poor.http.get_json(CATEGORIES_URL)
    results = poor.AttrDict(results)
    def get_recursive(item, level=1):
        children = item.get("categories", [])
        children = list(itertools.chain.from_iterable(
            get_recursive(x, level=level+1) for x in children))
        return [poor.AttrDict(label=item.get("name"), level=level)] + children
    types = list(get_recursive(results.response))
    return list(filter(lambda x: x.label, types))
Пример #14
0
 def _register(self, values, root=None, defaults=None):
     """Add entries for `values` if missing."""
     if root is None: root = self
     if defaults is None: defaults = DEFAULTS
     for name, value in values.items():
         if isinstance(value, dict):
             self._register(values[name],
                            root.setdefault(name, poor.AttrDict()),
                            defaults.setdefault(name, {}))
             continue
         # Do not change values if they already exist.
         root.setdefault(name, copy.deepcopy(value))
         defaults.setdefault(name, copy.deepcopy(value))
Пример #15
0
def route(fm, to, heading, params):
    """Find routes and return their properties as dictionaries."""
    fm, to = map(prepare_endpoint, (fm, to))
    region = poor.conf.routers.digitransit.region
    url = URL.format(**locals())
    modes = ",".join(poor.conf.routers.digitransit.modes)
    # Add optional parameters, None if missing.
    date = params.get("date", None)
    time = params.get("time", None)
    if date is None and time is not None:
        date = datetime.date.today().isoformat()
    arrive_by = params.get("arrive_by", None)
    optimize = poor.conf.routers.digitransit.optimize
    transfer_penalty = (600 if optimize == "least-transfers" else None)
    walk_reluctance = (10 if optimize == "least-walking" else None)
    body = BODY.format(**locals())
    body = re.sub(r"^.*\bNone\b.*$", "", body, flags=re.MULTILINE)
    body = "\n".join(x for x in body.splitlines() if x)
    result = poor.http.post_json(url, body, headers=HEADERS)
    result = poor.AttrDict(result)
    itineraries = result.data.plan.itineraries
    routes = [
        poor.AttrDict(
            alternative=i + 1,
            length=sum(x.distance for x in itinerary.legs),
            duration=float(itinerary.duration),
            legs=parse_legs(itinerary.legs),
        ) for i, itinerary in enumerate(itineraries)
    ]
    for route in routes:
        route.x = []
        route.y = []
        for leg in route.legs:
            route.x.extend(leg.pop("x"))
            route.y.extend(leg.pop("y"))
        route.maneuvers = parse_maneuvers(route)
        route.mode = "transit"
        route.attribution = poor.util.get_routing_attribution("Digitransit")
    return routes
Пример #16
0
def autocomplete_type(query, params=None):
    """Return a list of autocomplete dictionaries matching `query`."""
    if len(query) < 2: return []
    query = urllib.parse.quote_plus(query)
    url = CATEGORY_URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    results = poor.http.get_json(url)
    results = poor.AttrDict(results)
    results = [
        dict(label=r.displayString, sic=r.sic[0]) for r in results.results
    ]
    cache[url] = copy.deepcopy(results)
    return results
Пример #17
0
def autocomplete_type(query, params=None):
    """Return a list of autocomplete dictionaries matching `query`."""
    def normalize(x):
        # Relax matching for the common case of cafe vs. café.
        return x.lower().replace("é", "e")
    query = normalize(query)
    results = []
    for i, type in enumerate(get_types()):
        pos = normalize(type.label).find(query)
        if pos < 0: continue
        results.append(poor.AttrDict(
            label=type.label,
            order=(pos, type.level, type.label),
        ))
    results.sort(key=lambda x: x.order)
    results = [{"label": x["label"]} for x in results]
    return results[:100]
Пример #18
0
def route(locations, params):
    """Find route and return its properties as a dictionary."""
    loc = list(map(prepare_endpoint, locations))
    if len(loc) < 2: return None
    loc[0]["type"] = "break"  # pass through not supported for origin
    heading = params.get('heading', None)
    if heading is not None:
        loc[0]["heading"] = heading
    lang = poor.conf.routers.here.language
    units = "metric" if poor.conf.units == "metric" else "imperial"
    transportMode = poor.conf.routers.here.type
    traffic = poor.conf.routers.here.traffic
    routingMode = "short" if poor.conf.routers.here.shorter else "fast"
    origin = prepare_txtpoint(loc[0])
    destination = prepare_txtpoint(loc[-1])
    via = ''
    for point in loc[1:-1]:
        via += "&via=" + prepare_txtpoint(point)
    avoid = []
    if poor.conf.routers.here.avoid_car_train: avoid.append("carShuttleTrain")
    if transportMode == "truck" and poor.conf.routers.here.avoid_difficult_turn:
        avoid.append("difficultTurns")
    if poor.conf.routers.here.avoid_dirt: avoid.append("dirtRoad")
    if poor.conf.routers.here.avoid_highway:
        avoid.append("controlledAccessHighway")
    if poor.conf.routers.here.avoid_ferry: avoid.append("ferry")
    if poor.conf.routers.here.avoid_seasonal_closure:
        avoid.append("seasonalClosure")
    if poor.conf.routers.here.avoid_toll: avoid.append("tollRoad")
    if poor.conf.routers.here.avoid_tunnel: avoid.append("tunnel")
    if len(avoid) > 0:
        avoid = "&avoid[features]=" + (",".join(avoid))
    else:
        avoid = ""
    # skip cache if traffic update is expected
    skip_cache = traffic and transportMode in (["car", "bus", "taxi"])
    url = URL.format(**locals()) + via + avoid
    if not traffic: url += "&departureTime=any"
    if not skip_cache:
        with poor.util.silent(KeyError):
            return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    mode = MODE.get(transportMode, "car")
    return parse_result(url, locations, result, mode, lang, loc)
Пример #19
0
def route(locations, params):
    """Find route and return its properties as a dictionary."""
    locstring = ";".join(map(prepare_endpoint, locations))
    heading = params.get('heading', None)
    optimized = params.get('optimized', False) if len(locations) > 3 else False
    if optimized:
        url = URL_OPT.format(**locals())
    else:
        url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    routes = "trips" if optimized else "routes"
    result = poor.http.get_json(url)
    waypoints = result["waypoints"]
    result = poor.AttrDict(result[routes][0])
    x, y = poor.util.decode_epl(result.geometry)
    maneuvers, loc_index = [], [0]
    for leg in result.legs:
        maneuvers.extend([
            dict(
                x=float(step.maneuver.location[0]),
                y=float(step.maneuver.location[1]),
                icon=parse_icon(step.maneuver),
                narrative=parse_narrative(step.maneuver, step.get("name", "")),
                duration=float(step.duration),
                roundabout_exit_count=step.maneuver.get("exit", None),
            ) for step in leg.steps
        ])
        loc_index.append(loc_index[-1] + len(leg.annotation.nodes) - 1)
    if optimized:
        li = {waypoints[i]["waypoint_index"]: i for i in range(len(waypoints))}
        locations = [locations[li[i]] for i in range(len(waypoints))]
    route = dict(x=x,
                 y=y,
                 locations=locations,
                 location_indexes=loc_index,
                 maneuvers=maneuvers,
                 mode="car",
                 optimized=optimized)
    route["language"] = "en_US"
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #20
0
 def _update(self, values, root=None, defaults=None, path=()):
     """Load values of options after validation."""
     if root is None: root = self
     if defaults is None: defaults = DEFAULTS
     for name, value in values.items():
         if isinstance(value, dict):
             self._update(value, root.setdefault(name, poor.AttrDict()),
                          defaults.setdefault(name, {}), path + (name, ))
             continue
         try:
             if name in defaults:
                 # Be liberal, but careful in what to accept.
                 value = self._coerce(value, defaults[name])
             root[name] = copy.deepcopy(value)
         except Exception as error:
             full_name = ".".join(path + (name, ))
             print("Discarding bad option-value pair {}, {}: {}".format(
                 repr(full_name), repr(value), str(error)),
                   file=sys.stderr)
Пример #21
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    if heading is not None:
        fm["heading"] = heading
    lang = poor.util.get_default_language("en")
    input = dict(locations=[fm, to],
                 costing=poor.conf.routers.osmscout.type,
                 directions_options=dict(language=lang))

    input = urllib.parse.quote(json.dumps(input))
    url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    if result.get("API version", "") == "libosmscout V1":
        return parse_result_libosmscout(url, result)
    return parse_result_valhalla(url, result)
Пример #22
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fname = poor.conf.routers.gpx_osmscout.file
    language = poor.conf.routers.gpx_osmscout.language
    rev = poor.conf.routers.gpx_osmscout.reverse
    units = "kilometers" if poor.conf.units == "metric" else "miles"
    ctype = poor.conf.routers.gpx_osmscout.type
    x, y = poor.util.read_gpx(fname)
    shape = [dict(lat=y[i], lon=x[i]) for i in range(len(x))]
    if rev: shape = list(reversed(shape))
    input = dict(shape=shape,
                 shape_match="map_snap",
                 costing=ctype,
                 directions_options=dict(language=language, units=units))
    input = json.dumps({'json': json.dumps(input)})
    result = poor.http.post_json(URL, input)
    result = poor.AttrDict(result)
    mode = MODE.get(ctype, "car")
    return parse_result_valhalla(result, mode)
Пример #23
0
def nearby(query, near, radius, params):
    """Return X, Y and a list of dictionaries of places matching `query`."""
    query = urllib.parse.quote_plus(query)
    limit = params.get("limit", 50)
    name = params.get("name", "")
    name = urllib.parse.quote_plus(name)
    route_search = params.get("alongRoute", False)
    route = params.get("route", {})
    use_reference = params.get("fromReference", True)
    if route_search and not use_reference:
        url = URL_ROUTEONLY.format(**locals())
    elif isinstance(near, (list, tuple)):
        x, y = near[0], near[1]
        url = URL_XY.format(**locals())
    else:
        search = urllib.parse.quote_plus(near)
        url = URL_SEARCH.format(**locals())
    if route_search:
        results = poor.http.post_json(url, json.dumps(route))
    else:
        with poor.util.silent(KeyError):
            return copy.deepcopy(cache[url])
        results = poor.http.get_json(url)
    results = poor.AttrDict(results)
    x = float(results.origin.lng)
    y = float(results.origin.lat)
    results = [
        dict(
            address=parse_address(result),
            link=result.get("website", ""),
            phone=result.get("phone", ""),
            poi_type=parse_type(result),
            postcode=result.get("postal_code", ""),
            title=result.title,
            description=parse_description(result),
            distance=float(result.distance),
            x=float(result.lng),
            y=float(result.lat),
        ) for result in results.results
    ]
    if not route_search and results and results[0]:
        cache[url] = copy.deepcopy((x, y, results))
    return x, y, results
Пример #24
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    type = poor.conf.routers.mapquest_open.type
    locale = poor.conf.routers.mapquest_open.language
    locale = (locale if locale in SUPPORTED_LOCALES else "en_US")
    url = URL.format(**locals())
    if type == "fastest":
        # Assume all avoids are related to cars.
        for avoid in poor.conf.routers.mapquest_open.avoids:
            url += "&avoids={}".format(urllib.parse.quote_plus(avoid))
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)
    result = poor.AttrDict(result)
    x, y = poor.util.decode_epl(result.route.shape.shapePoints)
    maneuvers = []
    for leg in result.route.legs:
        maneuvers.extend(leg.maneuvers)
    maneuvers = [
        dict(
            x=float(maneuver.startPoint.lng),
            y=float(maneuver.startPoint.lat),
            icon=ICONS.get(maneuver.turnType, "flag"),
            narrative=maneuver.narrative,
            duration=float(maneuver.time),
            street=maneuver.get("streets", None),
        ) for maneuver in maneuvers
    ]
    if len(maneuvers) > 1:
        maneuvers[0]["icon"] = "depart"
        maneuvers[-1]["icon"] = "arrive"
    mode = MODE.get(type, "car")
    route = dict(x=x, y=y, maneuvers=maneuvers, mode=mode)
    route["language"] = locale
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #25
0
def route(fm, to, heading, params):
    """Find route and return its properties as a dictionary."""
    fm, to = map(prepare_endpoint, (fm, to))
    url = URL.format(**locals())
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url])
    result = poor.http.get_json(url)["routes"][0]
    result = poor.AttrDict(result)
    x, y = poor.util.decode_epl(result.geometry)
    maneuvers = [
        dict(
            x=float(step.maneuver.location[0]),
            y=float(step.maneuver.location[1]),
            icon=parse_icon(step.maneuver),
            narrative=parse_narrative(step.maneuver, step.get("name", "")),
            duration=float(step.duration),
        ) for step in result.legs[0].steps
    ]
    route = dict(x=x, y=y, maneuvers=maneuvers, mode="car")
    route["language"] = "en_US"
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #26
0
def parse_result(url, locations, result, mode, lang_translation,
                 locations_processed):
    """Parse and return route"""

    X, Y, Man, LocPointInd = [], [], [], [0]
    location_candidates = []
    for legs in result.routes[0].sections:
        x, y = [], []
        for p in poor.flexpolyline.decode(legs.polyline):
            x.append(p[1])
            y.append(p[0])

        instructions = {i.offset: i.instruction for i in legs.actions}
        language = legs.language
        transport_mode = legs.transport.mode
        maneuvers = []

        if "preActions" in legs:
            for maneuver in legs.preActions:
                m = dict(
                    x=float(x[0]),
                    y=float(y[0]),
                )
                m.update(
                    process_maneuver(maneuver,
                                     transport_mode=transport_mode,
                                     language=language,
                                     lang_translation=lang_translation,
                                     fill_narrative=True))
                maneuvers.append(m)

        # preprocess roundabouts
        for i in range(len(legs.turnByTurnActions) - 1):
            m0 = legs.turnByTurnActions[i]
            m1 = legs.turnByTurnActions[i + 1]
            if m0.action == "roundaboutEnter" and m1.action == "roundaboutExit":
                m0["exit"] = m1.get("exit", None)

        for maneuver in legs.turnByTurnActions:
            m = dict(
                x=float(x[maneuver.offset]),
                y=float(y[maneuver.offset]),
                narrative=instructions.get(maneuver.offset, None),
            )
            m.update(
                process_maneuver(maneuver,
                                 transport_mode=transport_mode,
                                 language=language,
                                 lang_translation=lang_translation,
                                 fill_narrative=(m["narrative"] is None)))
            maneuvers.append(m)

        if "postActions" in legs:
            for maneuver in legs.postActions:
                m = dict(
                    x=float(x[-1]),
                    y=float(y[-1]),
                )
                m.update(
                    process_maneuver(maneuver,
                                     transport_mode=transport_mode,
                                     language=language,
                                     lang_translation=lang_translation,
                                     fill_narrative=True))
                maneuvers.append(m)

        X.extend(x)
        Y.extend(y)
        Man.extend(maneuvers)
        location_candidates.append(
            poor.AttrDict(dict(index=len(X) - 1, x=x[-1], y=y[-1])))

    # HERE sets segments not always by waypoints. When boarding a
    # ferry, segment can be introduced without waypoint. When having
    # pass through waypoint, it is not reflected in segments
    ic = 0
    while len(LocPointInd) < len(locations_processed) - 1:
        target = locations_processed[len(LocPointInd)]
        if target["type"] == "break_through":
            LocPointInd.append(-1)  # will be found by navigator
            continue
        t_lat = target["lat"]
        t_lon = target["lon"]
        delta = [
            calculate_distance(c.x, c.y, t_lon, t_lat)
            for c in location_candidates[ic:-1]
        ]
        # move along locations and accept one which is reasonable
        # and close enough to the location. have to handle the
        # case where the same location is in the route multiple
        # times
        min_i = min(range(len(delta)), key=delta.__getitem__)
        min_v = delta[min_i]
        # check if we have multiple minima
        mins = [min_i]
        for i in range(1, len(delta) - 1):
            if i != min_i and delta[i] < 1.1 * min_v and delta[
                    i - 1] > delta[i] and delta[i + 1] > delta[i]:
                mins.append(i)
        # get the first minimum
        ic = ic + min(mins)
        LocPointInd.append(location_candidates[ic].index)
        ic += 1

    # add last location
    LocPointInd.append(location_candidates[-1].index)
    if len(LocPointInd) != len(locations_processed):
        print(
            "Error while filling location indexes. Please file and issue at the project page"
        )
        print("Data:", locations_processed, location_candidates, LocPointInd)
        return dict()

    route = dict(x=X,
                 y=Y,
                 locations=locations,
                 location_indexes=LocPointInd,
                 maneuvers=Man,
                 mode=mode)
    route["language"] = result.routes[0].sections[0].language.replace("-", "_")
    if route and route["x"]:
        cache[url] = copy.deepcopy(route)
    return route
Пример #27
0
def route(locations, params):
    """Find route and return its properties as a dictionary."""
    loc = list(map(prepare_endpoint, locations))
    heading = params.get('heading', None)
    optimized = params.get('optimized', False) if len(loc) > 3 else False
    type = poor.conf.routers.mapquest_open.type
    locale = poor.conf.routers.mapquest_open.language
    locale = (locale if locale in SUPPORTED_LOCALES else "en_US")
    service = "optimizedroute" if optimized else "route"
    url = URL.format(**locals())
    options = dict(ambiguities="ignore",
                   unit="k",
                   routeType=type,
                   doReverseGeocode=False,
                   shapeFormat="cmp",
                   generalize=5,
                   manMaps=False,
                   locale=locale)
    if type == "fastest":
        # Assume all avoids are related to cars.
        options["avoids"] = poor.conf.routers.mapquest_open.avoids
    input = dict(locations=loc, options=options)
    input = json.dumps(input)
    with poor.util.silent(KeyError):
        return copy.deepcopy(cache[url + input])
    result = poor.http.post_json(url, input)
    result = poor.AttrDict(result)
    # with open('route.json', 'w') as f:
    #     f.write(json.dumps(result))
    x, y = poor.util.decode_epl(result.route.shape.shapePoints)
    maneuvers = []
    for leg in result.route.legs:
        maneuvers.extend(leg.maneuvers)
    maneuvers = [
        dict(
            x=float(maneuver.startPoint.lng),
            y=float(maneuver.startPoint.lat),
            icon=ICONS.get(maneuver.turnType, "flag"),
            narrative=maneuver.narrative,
            duration=float(maneuver.time),
            street=maneuver.get("streets", None),
        ) for maneuver in maneuvers
    ]
    if len(maneuvers) > 1:
        maneuvers[0]["icon"] = "depart"
        maneuvers[-1]["icon"] = "arrive"
    loc_index = result.route.shape.legIndexes
    loc_index[-1] -= 1
    mode = MODE.get(type, "car")
    route = dict(
        x=x,
        y=y,
        locations=[locations[i] for i in result.route.locationSequence],
        location_indexes=loc_index,
        maneuvers=maneuvers,
        mode=mode,
        optimized=optimized)
    route["language"] = locale
    if route and route["x"]:
        cache[url + input] = copy.deepcopy(route)
    return route