Merge pull request #40 from yang-g/route
Add a dummy implementation of route_guide in c++.
This commit is contained in:
commit
1efae2547a
|
|
@ -0,0 +1,110 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
CXX = g++
|
||||
CPPFLAGS = -I/usr/local/include -pthread
|
||||
CXXFLAGS = -std=c++11
|
||||
LDFLAGS = -L/usr/local/lib -lgpr -lgrpc -lgrpc++ -lprotobuf -lpthread -ldl
|
||||
PROTOC = protoc
|
||||
GRPC_CPP_PLUGIN = grpc_cpp_plugin
|
||||
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
|
||||
|
||||
PROTOS_PATH = ../../protos
|
||||
|
||||
vpath %.proto $(PROTOS_PATH)
|
||||
|
||||
all: system-check route_guide_client route_guide_server
|
||||
|
||||
route_guide_client: route_guide.pb.o route_guide_client.o helper.o
|
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
route_guide_server: route_guide.pb.o route_guide_server.o helper.o
|
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
%.pb.cc: %.proto
|
||||
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
|
||||
|
||||
clean:
|
||||
rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server
|
||||
|
||||
|
||||
# The following is to test your system and ensure a smoother experience.
|
||||
# They are by no means necessary to actually compile a grpc-enabled software.
|
||||
|
||||
PROTOC_CMD = which $(PROTOC)
|
||||
PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3
|
||||
PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN)
|
||||
HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
|
||||
ifeq ($(HAS_PROTOC),true)
|
||||
HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
|
||||
endif
|
||||
HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)
|
||||
|
||||
SYSTEM_OK = false
|
||||
ifeq ($(HAS_VALID_PROTOC),true)
|
||||
ifeq ($(HAS_PLUGIN),true)
|
||||
SYSTEM_OK = true
|
||||
endif
|
||||
endif
|
||||
|
||||
system-check:
|
||||
ifneq ($(HAS_VALID_PROTOC),true)
|
||||
@echo " DEPENDENCY ERROR"
|
||||
@echo
|
||||
@echo "You don't have protoc 3.0.0 installed in your path."
|
||||
@echo "Please install Google protocol buffers 3.0.0 and its compiler."
|
||||
@echo "You can find it here:"
|
||||
@echo
|
||||
@echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1"
|
||||
@echo
|
||||
@echo "Here is what I get when trying to evaluate your version of protoc:"
|
||||
@echo
|
||||
-$(PROTOC) --version
|
||||
@echo
|
||||
@echo
|
||||
endif
|
||||
ifneq ($(HAS_PLUGIN),true)
|
||||
@echo " DEPENDENCY ERROR"
|
||||
@echo
|
||||
@echo "You don't have the grpc c++ protobuf plugin installed in your path."
|
||||
@echo "Please install grpc. You can find it here:"
|
||||
@echo
|
||||
@echo " https://github.com/grpc/grpc"
|
||||
@echo
|
||||
@echo "Here is what I get when trying to detect if you have the plugin:"
|
||||
@echo
|
||||
-which $(GRPC_CPP_PLUGIN)
|
||||
@echo
|
||||
@echo
|
||||
endif
|
||||
ifneq ($(SYSTEM_OK),true)
|
||||
@false
|
||||
endif
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
*
|
||||
* 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 <cctype>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "route_guide.pb.h"
|
||||
|
||||
namespace examples {
|
||||
|
||||
std::string GetDbFileContent(int argc, char** argv) {
|
||||
std::string db_path;
|
||||
std::string arg_str("--db_path");
|
||||
if (argc > 1) {
|
||||
std::string argv_1 = argv[1];
|
||||
size_t start_position = argv_1.find(arg_str);
|
||||
if (start_position != std::string::npos) {
|
||||
start_position += arg_str.size();
|
||||
if (argv_1[start_position] == ' ' ||
|
||||
argv_1[start_position] == '=') {
|
||||
db_path = argv_1.substr(start_position + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
db_path = "route_guide_db.json";
|
||||
}
|
||||
std::ifstream db_file(db_path);
|
||||
if (!db_file.is_open()) {
|
||||
std::cout << "Failed to open " << db_path << std::endl;
|
||||
return "";
|
||||
}
|
||||
std::stringstream db;
|
||||
db << db_file.rdbuf();
|
||||
return db.str();
|
||||
}
|
||||
|
||||
// A simple parser for the json db file. It requires the db file to have the
|
||||
// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name":
|
||||
// "the name can be empty" }, { ... } ... The spaces will be stripped.
|
||||
class Parser {
|
||||
public:
|
||||
explicit Parser(const std::string& db) : db_(db) {
|
||||
// Remove all spaces.
|
||||
db_.erase(
|
||||
std::remove_if(db_.begin(), db_.end(), isspace),
|
||||
db_.end());
|
||||
if (!Match("[")) {
|
||||
SetFailedAndReturnFalse();
|
||||
}
|
||||
}
|
||||
|
||||
bool Finished() {
|
||||
return current_ >= db_.size();
|
||||
}
|
||||
|
||||
bool TryParseOne(Feature* feature) {
|
||||
if (failed_ || Finished() || !Match("{")) {
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
if (!Match(location_) || !Match("{") || !Match(latitude_)) {
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
long temp = 0;
|
||||
ReadLong(&temp);
|
||||
feature->mutable_location()->set_latitude(temp);
|
||||
if (!Match(",") || !Match(longitude_)) {
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
ReadLong(&temp);
|
||||
feature->mutable_location()->set_longitude(temp);
|
||||
if (!Match("},") || !Match(name_) || !Match("\"")) {
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
size_t name_start = current_;
|
||||
while (current_ != db_.size() && db_[current_++] != '"') {
|
||||
}
|
||||
if (current_ == db_.size()) {
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
feature->set_name(db_.substr(name_start, current_-name_start-1));
|
||||
if (!Match("},")) {
|
||||
if (db_[current_ - 1] == ']' && current_ == db_.size()) {
|
||||
return true;
|
||||
}
|
||||
return SetFailedAndReturnFalse();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool SetFailedAndReturnFalse() {
|
||||
failed_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Match(const std::string& prefix) {
|
||||
bool eq = db_.substr(current_, prefix.size()) == prefix;
|
||||
current_ += prefix.size();
|
||||
return eq;
|
||||
}
|
||||
|
||||
void ReadLong(long* l) {
|
||||
size_t start = current_;
|
||||
while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') {
|
||||
current_++;
|
||||
}
|
||||
// It will throw an exception if fails.
|
||||
*l = std::stol(db_.substr(start, current_ - start));
|
||||
}
|
||||
|
||||
bool failed_ = false;
|
||||
std::string db_;
|
||||
size_t current_ = 0;
|
||||
const std::string location_ = "\"location\":";
|
||||
const std::string latitude_ = "\"latitude\":";
|
||||
const std::string longitude_ = "\"longitude\":";
|
||||
const std::string name_ = "\"name\":";
|
||||
};
|
||||
|
||||
void ParseDb(const std::string& db, std::vector<Feature>* feature_list) {
|
||||
feature_list->clear();
|
||||
std::string db_content(db);
|
||||
db_content.erase(
|
||||
std::remove_if(db_content.begin(), db_content.end(), isspace),
|
||||
db_content.end());
|
||||
|
||||
Parser parser(db_content);
|
||||
Feature feature;
|
||||
while (!parser.Finished()) {
|
||||
feature_list->push_back(Feature());
|
||||
if (!parser.TryParseOne(&feature_list->back())) {
|
||||
std::cout << "Error parsing the db file";
|
||||
feature_list->clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::cout << "DB parsed, loaded " << feature_list->size()
|
||||
<< " features." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
} // namespace examples
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
|
||||
#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace examples {
|
||||
class Feature;
|
||||
|
||||
std::string GetDbFileContent(int argc, char** argv);
|
||||
|
||||
void ParseDb(const std::string& db, std::vector<Feature>* feature_list);
|
||||
|
||||
} // namespace examples
|
||||
|
||||
#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
|
||||
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
*
|
||||
* 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 <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc++/channel_arguments.h>
|
||||
#include <grpc++/channel_interface.h>
|
||||
#include <grpc++/client_context.h>
|
||||
#include <grpc++/create_channel.h>
|
||||
#include <grpc++/status.h>
|
||||
#include <grpc++/stream.h>
|
||||
#include "helper.h"
|
||||
#include "route_guide.pb.h"
|
||||
|
||||
using grpc::ChannelArguments;
|
||||
using grpc::ChannelInterface;
|
||||
using grpc::ClientContext;
|
||||
using grpc::ClientReader;
|
||||
using grpc::ClientReaderWriter;
|
||||
using grpc::ClientWriter;
|
||||
using grpc::Status;
|
||||
using examples::Point;
|
||||
using examples::Feature;
|
||||
using examples::Rectangle;
|
||||
using examples::RouteSummary;
|
||||
using examples::RouteNote;
|
||||
using examples::RouteGuide;
|
||||
|
||||
Point MakePoint(long latitude, long longitude) {
|
||||
Point p;
|
||||
p.set_latitude(latitude);
|
||||
p.set_longitude(longitude);
|
||||
return p;
|
||||
}
|
||||
|
||||
Feature MakeFeature(const std::string& name,
|
||||
long latitude, long longitude) {
|
||||
Feature f;
|
||||
f.set_name(name);
|
||||
f.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
|
||||
return f;
|
||||
}
|
||||
|
||||
RouteNote MakeRouteNote(const std::string& message,
|
||||
long latitude, long longitude) {
|
||||
RouteNote n;
|
||||
n.set_message(message);
|
||||
n.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
|
||||
return n;
|
||||
}
|
||||
|
||||
class RouteGuideClient {
|
||||
public:
|
||||
RouteGuideClient(std::shared_ptr<ChannelInterface> channel,
|
||||
const std::string& db)
|
||||
: stub_(RouteGuide::NewStub(channel)) {
|
||||
examples::ParseDb(db, &feature_list_);
|
||||
}
|
||||
|
||||
void GetFeature() {
|
||||
Point point;
|
||||
Feature feature;
|
||||
point = MakePoint(409146138, -746188906);
|
||||
GetOneFeature(point, &feature);
|
||||
point = MakePoint(0, 0);
|
||||
GetOneFeature(point, &feature);
|
||||
}
|
||||
|
||||
void ListFeatures() {
|
||||
Rectangle rect;
|
||||
Feature feature;
|
||||
ClientContext context;
|
||||
|
||||
rect.mutable_lo()->set_latitude(400000000);
|
||||
rect.mutable_lo()->set_longitude(-750000000);
|
||||
rect.mutable_hi()->set_latitude(420000000);
|
||||
rect.mutable_hi()->set_longitude(-730000000);
|
||||
std::cout << "Looking for features between 40, -75 and 42, -73"
|
||||
<< std::endl;
|
||||
|
||||
std::unique_ptr<ClientReader<Feature> > reader(
|
||||
stub_->ListFeatures(&context, rect));
|
||||
while (reader->Read(&feature)) {
|
||||
std::cout << "Found feature called "
|
||||
<< feature.name() << " at "
|
||||
<< feature.location().latitude()/kCoordFactor_ << ", "
|
||||
<< feature.location().latitude()/kCoordFactor_ << std::endl;
|
||||
}
|
||||
Status status = reader->Finish();
|
||||
if (status.IsOk()) {
|
||||
std::cout << "ListFeatures rpc succeeded." << std::endl;
|
||||
} else {
|
||||
std::cout << "ListFeatures rpc failed." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordRoute() {
|
||||
Point point;
|
||||
RouteSummary stats;
|
||||
ClientContext context;
|
||||
const int kPoints = 10;
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
|
||||
std::default_random_engine generator(seed);
|
||||
std::uniform_int_distribution<int> feature_distribution(
|
||||
0, feature_list_.size() - 1);
|
||||
std::uniform_int_distribution<int> delay_distribution(
|
||||
500, 1500);
|
||||
|
||||
std::unique_ptr<ClientWriter<Point> > writer(
|
||||
stub_->RecordRoute(&context, &stats));
|
||||
for (int i = 0; i < kPoints; i++) {
|
||||
const Feature& f = feature_list_[feature_distribution(generator)];
|
||||
std::cout << "Visiting point "
|
||||
<< f.location().latitude()/kCoordFactor_ << ", "
|
||||
<< f.location().longitude()/kCoordFactor_ << std::endl;
|
||||
if (!writer->Write(f.location())) {
|
||||
// Broken stream.
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(
|
||||
delay_distribution(generator)));
|
||||
}
|
||||
writer->WritesDone();
|
||||
Status status = writer->Finish();
|
||||
if (status.IsOk()) {
|
||||
std::cout << "Finished trip with " << stats.point_count() << " points\n"
|
||||
<< "Passed " << stats.feature_count() << " features\n"
|
||||
<< "Travelled " << stats.distance() << " meters\n"
|
||||
<< "It took " << stats.elapsed_time() << " seconds"
|
||||
<< std::endl;
|
||||
} else {
|
||||
std::cout << "RecordRoute rpc failed." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteChat() {
|
||||
ClientContext context;
|
||||
|
||||
std::shared_ptr<ClientReaderWriter<RouteNote, RouteNote> > stream(
|
||||
stub_->RouteChat(&context));
|
||||
|
||||
std::thread writer([stream]() {
|
||||
std::vector<RouteNote> notes{
|
||||
MakeRouteNote("First message", 0, 0),
|
||||
MakeRouteNote("Second message", 0, 1),
|
||||
MakeRouteNote("Third message", 1, 0),
|
||||
MakeRouteNote("Fourth message", 0, 0)};
|
||||
for (const RouteNote& note : notes) {
|
||||
std::cout << "Sending message " << note.message()
|
||||
<< " at " << note.location().latitude() << ", "
|
||||
<< note.location().longitude() << std::endl;
|
||||
stream->Write(note);
|
||||
}
|
||||
stream->WritesDone();
|
||||
});
|
||||
|
||||
RouteNote server_note;
|
||||
while (stream->Read(&server_note)) {
|
||||
std::cout << "Got message " << server_note.message()
|
||||
<< " at " << server_note.location().latitude() << ", "
|
||||
<< server_note.location().longitude() << std::endl;
|
||||
}
|
||||
writer.join();
|
||||
Status status = stream->Finish();
|
||||
if (!status.IsOk()) {
|
||||
std::cout << "RouteChat rpc failed." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown() { stub_.reset(); }
|
||||
|
||||
private:
|
||||
|
||||
bool GetOneFeature(const Point& point, Feature* feature) {
|
||||
ClientContext context;
|
||||
Status status = stub_->GetFeature(&context, point, feature);
|
||||
if (!status.IsOk()) {
|
||||
std::cout << "GetFeature rpc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!feature->has_location()) {
|
||||
std::cout << "Server returns incomplete feature." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (feature->name().empty()) {
|
||||
std::cout << "Found no feature at "
|
||||
<< feature->location().latitude()/kCoordFactor_ << ", "
|
||||
<< feature->location().longitude()/kCoordFactor_ << std::endl;
|
||||
} else {
|
||||
std::cout << "Found feature called " << feature->name() << " at "
|
||||
<< feature->location().latitude()/kCoordFactor_ << ", "
|
||||
<< feature->location().longitude()/kCoordFactor_ << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const float kCoordFactor_ = 10000000.0;
|
||||
std::unique_ptr<RouteGuide::Stub> stub_;
|
||||
std::vector<Feature> feature_list_;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc_init();
|
||||
|
||||
// Expect only arg: --db_path=path/to/route_guide_db.json.
|
||||
std::string db = examples::GetDbFileContent(argc, argv);
|
||||
RouteGuideClient guide(
|
||||
grpc::CreateChannelDeprecated("localhost:50051", ChannelArguments()),
|
||||
db);
|
||||
|
||||
std::cout << "-------------- GetFeature --------------" << std::endl;
|
||||
guide.GetFeature();
|
||||
std::cout << "-------------- ListFeatures --------------" << std::endl;
|
||||
guide.ListFeatures();
|
||||
std::cout << "-------------- RecordRoute --------------" << std::endl;
|
||||
guide.RecordRoute();
|
||||
std::cout << "-------------- RouteChat --------------" << std::endl;
|
||||
guide.RouteChat();
|
||||
|
||||
guide.Shutdown();
|
||||
|
||||
grpc_shutdown();
|
||||
}
|
||||
|
|
@ -0,0 +1,601 @@
|
|||
[{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}]
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
*
|
||||
* 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 <thread>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc++/server.h>
|
||||
#include <grpc++/server_builder.h>
|
||||
#include <grpc++/server_context.h>
|
||||
#include <grpc++/status.h>
|
||||
#include <grpc++/stream.h>
|
||||
#include "helper.h"
|
||||
#include "route_guide.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 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(¬e)) {
|
||||
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.AddPort(server_address);
|
||||
builder.RegisterService(&service);
|
||||
std::unique_ptr<Server> server(builder.BuildAndStart());
|
||||
std::cout << "Server listening on " << server_address << std::endl;
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc_init();
|
||||
|
||||
// Expect only arg: --db_path=path/to/route_guide_db.json.
|
||||
std::string db = examples::GetDbFileContent(argc, argv);
|
||||
RunServer(db);
|
||||
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue