aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/cpp/route_guide/route_guide_server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cpp/route_guide/route_guide_server.cc')
-rw-r--r--examples/cpp/route_guide/route_guide_server.cc202
1 files changed, 202 insertions, 0 deletions
diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc
new file mode 100644
index 0000000000..b37539299a
--- /dev/null
+++ b/examples/cpp/route_guide/route_guide_server.cc
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include "helper.h"
+#include "route_guide.grpc.pb.h"
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerReader;
+using grpc::ServerReaderWriter;
+using grpc::ServerWriter;
+using grpc::Status;
+using examples::Point;
+using examples::Feature;
+using examples::Rectangle;
+using examples::RouteSummary;
+using examples::RouteNote;
+using examples::RouteGuide;
+using std::chrono::system_clock;
+
+
+float ConvertToRadians(float num) {
+ return num * 3.1415926 /180;
+}
+
+float GetDistance(const Point& start, const Point& end) {
+ const float kCoordFactor = 10000000.0;
+ float lat_1 = start.latitude() / kCoordFactor;
+ float lat_2 = end.latitude() / kCoordFactor;
+ float lon_1 = start.longitude() / kCoordFactor;
+ float lon_2 = end.longitude() / kCoordFactor;
+ float lat_rad_1 = ConvertToRadians(lat_1);
+ float lat_rad_2 = ConvertToRadians(lat_2);
+ float delta_lat_rad = ConvertToRadians(lat_2-lat_1);
+ float delta_lon_rad = ConvertToRadians(lon_2-lon_1);
+
+ float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) *
+ pow(sin(delta_lon_rad/2), 2);
+ float c = 2 * atan2(sqrt(a), sqrt(1-a));
+ int R = 6371000; // metres
+
+ return R * c;
+}
+
+std::string GetFeatureName(const Point& point,
+ const std::vector<Feature>& feature_list) {
+ for (const Feature& f : feature_list) {
+ if (f.location().latitude() == point.latitude() &&
+ f.location().longitude() == point.longitude()) {
+ return f.name();
+ }
+ }
+ return "";
+}
+
+class RouteGuideImpl final : public RouteGuide::Service {
+ public:
+ explicit RouteGuideImpl(const std::string& db) {
+ examples::ParseDb(db, &feature_list_);
+ }
+
+ Status GetFeature(ServerContext* context, const Point* point,
+ Feature* feature) override {
+ feature->set_name(GetFeatureName(*point, feature_list_));
+ feature->mutable_location()->CopyFrom(*point);
+ return Status::OK;
+ }
+
+ Status ListFeatures(ServerContext* context,
+ const examples::Rectangle* rectangle,
+ ServerWriter<Feature>* writer) override {
+ auto lo = rectangle->lo();
+ auto hi = rectangle->hi();
+ long left = (std::min)(lo.longitude(), hi.longitude());
+ long right = (std::max)(lo.longitude(), hi.longitude());
+ long top = (std::max)(lo.latitude(), hi.latitude());
+ long bottom = (std::min)(lo.latitude(), hi.latitude());
+ for (const Feature& f : feature_list_) {
+ if (f.location().longitude() >= left &&
+ f.location().longitude() <= right &&
+ f.location().latitude() >= bottom &&
+ f.location().latitude() <= top) {
+ writer->Write(f);
+ }
+ }
+ return Status::OK;
+ }
+
+ Status RecordRoute(ServerContext* context, ServerReader<Point>* reader,
+ RouteSummary* summary) override {
+ Point point;
+ int point_count = 0;
+ int feature_count = 0;
+ float distance = 0.0;
+ Point previous;
+
+ system_clock::time_point start_time = system_clock::now();
+ while (reader->Read(&point)) {
+ point_count++;
+ if (!GetFeatureName(point, feature_list_).empty()) {
+ feature_count++;
+ }
+ if (point_count != 1) {
+ distance += GetDistance(previous, point);
+ }
+ previous = point;
+ }
+ system_clock::time_point end_time = system_clock::now();
+ summary->set_point_count(point_count);
+ summary->set_feature_count(feature_count);
+ summary->set_distance(static_cast<long>(distance));
+ auto secs = std::chrono::duration_cast<std::chrono::seconds>(
+ end_time - start_time);
+ summary->set_elapsed_time(secs.count());
+
+ return Status::OK;
+ }
+
+ Status RouteChat(ServerContext* context,
+ ServerReaderWriter<RouteNote, RouteNote>* stream) override {
+ std::vector<RouteNote> received_notes;
+ RouteNote note;
+ while (stream->Read(&note)) {
+ for (const RouteNote& n : received_notes) {
+ if (n.location().latitude() == note.location().latitude() &&
+ n.location().longitude() == note.location().longitude()) {
+ stream->Write(n);
+ }
+ }
+ received_notes.push_back(note);
+ }
+
+ return Status::OK;
+ }
+
+ private:
+
+ std::vector<Feature> feature_list_;
+};
+
+void RunServer(const std::string& db_path) {
+ std::string server_address("0.0.0.0:50051");
+ RouteGuideImpl service(db_path);
+
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ builder.RegisterService(&service);
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ // Expect only arg: --db_path=path/to/route_guide_db.json.
+ std::string db = examples::GetDbFileContent(argc, argv);
+ RunServer(db);
+
+ return 0;
+}