def _get_query(self): params = self.request.params term = params.get('term', '').strip() if term: waypoints = re.split('\s+to\s+', term, re.I) if len(waypoints) < 2: raise InputError( "That doesn't look like a valid directions request") else: waypoints = params.get('waypoints', '').strip() if waypoints: waypoints = waypoints.split(';') start, *rest = waypoints end = rest[-1] if rest else None else: start = params.get('from', '').strip() end = params.get('to', '').strip() if start and end: waypoints = [start, end] elif start: raise InputError('Please enter a starting point') elif end: raise InputError('Please enter a destination') else: raise InputError('Please enter something to search for') return waypoints
def _get(self): req = self.request params = req.params has_directions_params = 'from' in params or 'to' in params if 'term'in params: if has_directions_params: self.request.response.status_int = 400 raise InputError( 'Query service accepts *either* the `term` query parameter *or* the `from` ' 'and `to` query parameters') term = params.get('term', '').strip() if DIRECTIONS_RE.match(term): view_class = DirectionsResource else: view_class = LookupResource elif has_directions_params: view_class = DirectionsResource else: raise InputError( 'Query service requires at least one of the following query parameter: ' '`term`, `from`, or `to`') view = view_class(self.request) return view.get()
def _get_config(self): """Get configuration for service. Extract service config from query params and return a dict of keyword args that will be passed when constructing the service instance. Raises: InputError: On bad input """ center = self.request.params.get('center', '').strip() if center: coords = center.split(',') coords = tuple(c.strip() for c in coords) coords = tuple(c for c in coords if c) if not (len(center) == 2 and all(is_coord(c for c in coords))): raise InputError('center param must contain exactly 2 numbers (comma separated)') center = tuple(float(c) for c in coords) bbox = self.request.params.get('bbox', '').strip() if bbox: coords = bbox.split(',') coords = tuple(c.strip() for c in coords) coords = tuple(c for c in coords if c) if not (len(coords) == 4 and all(is_coord(c for c in coords))): raise InputError('bbox param must contain exactly 4 numbers (comma separated)') if coords[0] > coords[2]: raise InputError('bbox param minx must be less than maxx') if coords[1] > coords[3]: raise InputError('bbox param miny must be less than maxy') bbox = tuple(float(c) for c in coords) else: bbox = self._default_bbox settings = self.request.registry.settings mapbox_access_token = settings.get('mapbox.access_token') return { 'center': center or None, 'bbox': bbox or None, 'mapbox_access_token': mapbox_access_token, }
def match_id(self, s): match = ID_RE.search(s) if match: type_ = match.group('type') if type_ not in TYPE_MAP: raise InputError('Unknown type: %s' % type_) type_ = TYPE_MAP[type_] obj = self.session.query(type_).get(match.group('id')) if obj is None: return None if isinstance(obj, Intersection): geom = obj.geom else: length = obj.geom.length geom = Point(obj.geom.interpolate(length / 2)) return LookupResult(s, obj, geom, obj, obj.name, 'byCycle ID')
def get_waypoints(self, q, points=None): errors = [] waypoints = [w.strip() for w in q] num_waypoints = len(waypoints) points = points or [None] * num_waypoints if num_waypoints != len(points): errors.append( 'Number of points does not match number of waypoints') if num_waypoints == 0: errors.append('Please enter starting point and destination') if num_waypoints == 1: errors.append('Please enter a destination') else: if num_waypoints == 2: if not waypoints[0]: errors.append('Please enter a starting point') if not waypoints[-1]: errors.append('Please enter a destination') else: for w in waypoints: if not w: errors.append('Destinations cannot be blank') break if errors: raise InputError(errors) lookup_service = LookupService(self.session, **self.config) results = [] raise_multi = False for w, point_hint in zip(waypoints, points): try: result = lookup_service.query(w, point_hint) except MultipleLookupResultsError as exc: raise_multi = True results.append(exc.choices) else: results.append(result) if raise_multi: raise MultipleRouteLookupResultsError(choices=results) return results
def _get_query(self): params = self.request.params term = params.get('term', '').strip() if not term: raise InputError('Please enter something to search for.') return term
def find_path(self, start_result: LookupResult, end_result: LookupResult, cost_func: str = None, heuristic_func: str = None): client = Client() start = start_result.closest_object end = end_result.closest_object annex_edges = [] split_ways = {} add_between = isinstance(start, Street) and isinstance( end, Street) and start.id == end.id if isinstance(start, Street): start, *start_ways, start_edges = self.split_way( start, start_result.geom, -1, -1, -2) annex_edges.extend(start_edges) split_ways.update({w.id: w for w in start_ways}) if isinstance(end, Street): end, *end_ways, end_edges = self.split_way(end, end_result.geom, -2, -3, -4) annex_edges.extend(end_edges) split_ways.update({w.id: w for w in end_ways}) if add_between: obj = start_result.closest_object geom = trim_line(obj.geom, start.geom, end.geom) d1 = obj.geom.project(start.geom) d2 = obj.geom.project(end.geom) if d1 <= d2: start_node, end_node = start, end else: start_node, end_node = end, start if obj.base_cost is None: base_cost = None else: fraction = length_in_meters(geom) / obj.meters base_cost = obj.base_cost * fraction way = obj.clone(id=-3, geom=geom, start_node_id=start_node.id, start_node=start_node, end_node_id=end_node.id, end_node=end_node, base_cost=base_cost) way_attrs = (way.id, base_cost, way.name) annex_edges.append((start_node.id, end_node.id, way_attrs)) if not way.oneway_bicycle: annex_edges.append((end_node.id, start_node.id, way_attrs)) split_ways[way.id] = way try: result = client.find_path(start.id, end.id, annex_edges=annex_edges, cost_func=cost_func, heuristic_func=heuristic_func, fields=('nodes', 'edges')) except ClientError as exc: status_code = exc.response.status_code data = exc.response.json() detail = data['detail'] if status_code == 400: raise InputError(detail) if status_code == 404: raise NoRouteError(start_result, end_result) raise nodes = result['nodes'] edges = [edge[0] for edge in result['edges']] assert nodes[ 0] == start.id, f'Expected route start node ID: {start.id}; got {nodes[0]}' assert nodes[ -1] == end.id, f'Expected route end node ID: {start.id}; got {nodes[-1]}' return nodes, edges, split_ways