1*cc02d7e2SAndroid Build Coastguard Worker# Copyright 2016 gRPC authors. 2*cc02d7e2SAndroid Build Coastguard Worker# 3*cc02d7e2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*cc02d7e2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*cc02d7e2SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*cc02d7e2SAndroid Build Coastguard Worker# 7*cc02d7e2SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*cc02d7e2SAndroid Build Coastguard Worker# 9*cc02d7e2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*cc02d7e2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*cc02d7e2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*cc02d7e2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*cc02d7e2SAndroid Build Coastguard Worker# limitations under the License. 14*cc02d7e2SAndroid Build Coastguard Worker"""A gRPC server servicing both Greeter and RouteGuide RPCs.""" 15*cc02d7e2SAndroid Build Coastguard Worker 16*cc02d7e2SAndroid Build Coastguard Workerfrom concurrent import futures 17*cc02d7e2SAndroid Build Coastguard Workerimport logging 18*cc02d7e2SAndroid Build Coastguard Workerimport math 19*cc02d7e2SAndroid Build Coastguard Workerimport time 20*cc02d7e2SAndroid Build Coastguard Worker 21*cc02d7e2SAndroid Build Coastguard Workerimport grpc 22*cc02d7e2SAndroid Build Coastguard Workerimport helloworld_pb2 23*cc02d7e2SAndroid Build Coastguard Workerimport helloworld_pb2_grpc 24*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_pb2 25*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_pb2_grpc 26*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_resources 27*cc02d7e2SAndroid Build Coastguard Worker 28*cc02d7e2SAndroid Build Coastguard Worker 29*cc02d7e2SAndroid Build Coastguard Workerdef _get_feature(feature_db, point): 30*cc02d7e2SAndroid Build Coastguard Worker """Returns Feature at given location or None.""" 31*cc02d7e2SAndroid Build Coastguard Worker for feature in feature_db: 32*cc02d7e2SAndroid Build Coastguard Worker if feature.location == point: 33*cc02d7e2SAndroid Build Coastguard Worker return feature 34*cc02d7e2SAndroid Build Coastguard Worker return None 35*cc02d7e2SAndroid Build Coastguard Worker 36*cc02d7e2SAndroid Build Coastguard Worker 37*cc02d7e2SAndroid Build Coastguard Workerdef _get_distance(start, end): 38*cc02d7e2SAndroid Build Coastguard Worker """Distance between two points.""" 39*cc02d7e2SAndroid Build Coastguard Worker coord_factor = 10000000.0 40*cc02d7e2SAndroid Build Coastguard Worker lat_1 = start.latitude / coord_factor 41*cc02d7e2SAndroid Build Coastguard Worker lat_2 = end.latitude / coord_factor 42*cc02d7e2SAndroid Build Coastguard Worker lon_1 = start.longitude / coord_factor 43*cc02d7e2SAndroid Build Coastguard Worker lon_2 = end.longitude / coord_factor 44*cc02d7e2SAndroid Build Coastguard Worker lat_rad_1 = math.radians(lat_1) 45*cc02d7e2SAndroid Build Coastguard Worker lat_rad_2 = math.radians(lat_2) 46*cc02d7e2SAndroid Build Coastguard Worker delta_lat_rad = math.radians(lat_2 - lat_1) 47*cc02d7e2SAndroid Build Coastguard Worker delta_lon_rad = math.radians(lon_2 - lon_1) 48*cc02d7e2SAndroid Build Coastguard Worker 49*cc02d7e2SAndroid Build Coastguard Worker a = pow(math.sin(delta_lat_rad / 2), 2) + ( 50*cc02d7e2SAndroid Build Coastguard Worker math.cos(lat_rad_1) 51*cc02d7e2SAndroid Build Coastguard Worker * math.cos(lat_rad_2) 52*cc02d7e2SAndroid Build Coastguard Worker * pow(math.sin(delta_lon_rad / 2), 2) 53*cc02d7e2SAndroid Build Coastguard Worker ) 54*cc02d7e2SAndroid Build Coastguard Worker c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) 55*cc02d7e2SAndroid Build Coastguard Worker R = 6371000 56*cc02d7e2SAndroid Build Coastguard Worker # metres 57*cc02d7e2SAndroid Build Coastguard Worker return R * c 58*cc02d7e2SAndroid Build Coastguard Worker 59*cc02d7e2SAndroid Build Coastguard Worker 60*cc02d7e2SAndroid Build Coastguard Workerclass _GreeterServicer(helloworld_pb2_grpc.GreeterServicer): 61*cc02d7e2SAndroid Build Coastguard Worker def SayHello(self, request, context): 62*cc02d7e2SAndroid Build Coastguard Worker return helloworld_pb2.HelloReply( 63*cc02d7e2SAndroid Build Coastguard Worker message="Hello, {}!".format(request.name) 64*cc02d7e2SAndroid Build Coastguard Worker ) 65*cc02d7e2SAndroid Build Coastguard Worker 66*cc02d7e2SAndroid Build Coastguard Worker 67*cc02d7e2SAndroid Build Coastguard Workerclass _RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer): 68*cc02d7e2SAndroid Build Coastguard Worker """Provides methods that implement functionality of route guide server.""" 69*cc02d7e2SAndroid Build Coastguard Worker 70*cc02d7e2SAndroid Build Coastguard Worker def __init__(self): 71*cc02d7e2SAndroid Build Coastguard Worker self.db = route_guide_resources.read_route_guide_database() 72*cc02d7e2SAndroid Build Coastguard Worker 73*cc02d7e2SAndroid Build Coastguard Worker def GetFeature(self, request, context): 74*cc02d7e2SAndroid Build Coastguard Worker feature = _get_feature(self.db, request) 75*cc02d7e2SAndroid Build Coastguard Worker if feature is None: 76*cc02d7e2SAndroid Build Coastguard Worker return route_guide_pb2.Feature(name="", location=request) 77*cc02d7e2SAndroid Build Coastguard Worker else: 78*cc02d7e2SAndroid Build Coastguard Worker return feature 79*cc02d7e2SAndroid Build Coastguard Worker 80*cc02d7e2SAndroid Build Coastguard Worker def ListFeatures(self, request, context): 81*cc02d7e2SAndroid Build Coastguard Worker left = min(request.lo.longitude, request.hi.longitude) 82*cc02d7e2SAndroid Build Coastguard Worker right = max(request.lo.longitude, request.hi.longitude) 83*cc02d7e2SAndroid Build Coastguard Worker top = max(request.lo.latitude, request.hi.latitude) 84*cc02d7e2SAndroid Build Coastguard Worker bottom = min(request.lo.latitude, request.hi.latitude) 85*cc02d7e2SAndroid Build Coastguard Worker for feature in self.db: 86*cc02d7e2SAndroid Build Coastguard Worker if ( 87*cc02d7e2SAndroid Build Coastguard Worker feature.location.longitude >= left 88*cc02d7e2SAndroid Build Coastguard Worker and feature.location.longitude <= right 89*cc02d7e2SAndroid Build Coastguard Worker and feature.location.latitude >= bottom 90*cc02d7e2SAndroid Build Coastguard Worker and feature.location.latitude <= top 91*cc02d7e2SAndroid Build Coastguard Worker ): 92*cc02d7e2SAndroid Build Coastguard Worker yield feature 93*cc02d7e2SAndroid Build Coastguard Worker 94*cc02d7e2SAndroid Build Coastguard Worker def RecordRoute(self, request_iterator, context): 95*cc02d7e2SAndroid Build Coastguard Worker point_count = 0 96*cc02d7e2SAndroid Build Coastguard Worker feature_count = 0 97*cc02d7e2SAndroid Build Coastguard Worker distance = 0.0 98*cc02d7e2SAndroid Build Coastguard Worker prev_point = None 99*cc02d7e2SAndroid Build Coastguard Worker 100*cc02d7e2SAndroid Build Coastguard Worker start_time = time.time() 101*cc02d7e2SAndroid Build Coastguard Worker for point in request_iterator: 102*cc02d7e2SAndroid Build Coastguard Worker point_count += 1 103*cc02d7e2SAndroid Build Coastguard Worker if _get_feature(self.db, point): 104*cc02d7e2SAndroid Build Coastguard Worker feature_count += 1 105*cc02d7e2SAndroid Build Coastguard Worker if prev_point: 106*cc02d7e2SAndroid Build Coastguard Worker distance += _get_distance(prev_point, point) 107*cc02d7e2SAndroid Build Coastguard Worker prev_point = point 108*cc02d7e2SAndroid Build Coastguard Worker 109*cc02d7e2SAndroid Build Coastguard Worker elapsed_time = time.time() - start_time 110*cc02d7e2SAndroid Build Coastguard Worker return route_guide_pb2.RouteSummary( 111*cc02d7e2SAndroid Build Coastguard Worker point_count=point_count, 112*cc02d7e2SAndroid Build Coastguard Worker feature_count=feature_count, 113*cc02d7e2SAndroid Build Coastguard Worker distance=int(distance), 114*cc02d7e2SAndroid Build Coastguard Worker elapsed_time=int(elapsed_time), 115*cc02d7e2SAndroid Build Coastguard Worker ) 116*cc02d7e2SAndroid Build Coastguard Worker 117*cc02d7e2SAndroid Build Coastguard Worker def RouteChat(self, request_iterator, context): 118*cc02d7e2SAndroid Build Coastguard Worker prev_notes = [] 119*cc02d7e2SAndroid Build Coastguard Worker for new_note in request_iterator: 120*cc02d7e2SAndroid Build Coastguard Worker for prev_note in prev_notes: 121*cc02d7e2SAndroid Build Coastguard Worker if prev_note.location == new_note.location: 122*cc02d7e2SAndroid Build Coastguard Worker yield prev_note 123*cc02d7e2SAndroid Build Coastguard Worker prev_notes.append(new_note) 124*cc02d7e2SAndroid Build Coastguard Worker 125*cc02d7e2SAndroid Build Coastguard Worker 126*cc02d7e2SAndroid Build Coastguard Workerdef serve(): 127*cc02d7e2SAndroid Build Coastguard Worker server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 128*cc02d7e2SAndroid Build Coastguard Worker helloworld_pb2_grpc.add_GreeterServicer_to_server( 129*cc02d7e2SAndroid Build Coastguard Worker _GreeterServicer(), server 130*cc02d7e2SAndroid Build Coastguard Worker ) 131*cc02d7e2SAndroid Build Coastguard Worker route_guide_pb2_grpc.add_RouteGuideServicer_to_server( 132*cc02d7e2SAndroid Build Coastguard Worker _RouteGuideServicer(), server 133*cc02d7e2SAndroid Build Coastguard Worker ) 134*cc02d7e2SAndroid Build Coastguard Worker server.add_insecure_port("[::]:50051") 135*cc02d7e2SAndroid Build Coastguard Worker server.start() 136*cc02d7e2SAndroid Build Coastguard Worker server.wait_for_termination() 137*cc02d7e2SAndroid Build Coastguard Worker 138*cc02d7e2SAndroid Build Coastguard Worker 139*cc02d7e2SAndroid Build Coastguard Workerif __name__ == "__main__": 140*cc02d7e2SAndroid Build Coastguard Worker logging.basicConfig() 141*cc02d7e2SAndroid Build Coastguard Worker serve() 142