mirror of https://github.com/grpc/grpc.git
The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.9 KiB
183 lines
5.9 KiB
4 years ago
|
<?php
|
||
|
/*
|
||
|
*
|
||
|
* Copyright 2020 gRPC authors.
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
class RouteGuideService extends \Routeguide\RouteGuideStub
|
||
|
{
|
||
|
public function __construct($dbFilePath)
|
||
|
{
|
||
|
$dbFilePath = $dbFilePath ?? dirname(__FILE__) . '/route_guide_db.json';
|
||
|
$dbData = file_get_contents($dbFilePath);
|
||
|
if (!$dbData) {
|
||
|
throw new InvalidArgumentException(
|
||
|
"Error reading route db file: " . $dbFilePath
|
||
|
);
|
||
|
}
|
||
|
$featureList = json_decode($dbData);
|
||
|
if (!$featureList) {
|
||
|
throw new InvalidArgumentException(
|
||
|
"Error decoding route db file: " . $dbFilePath
|
||
|
);
|
||
|
}
|
||
|
foreach ($featureList as $feature) {
|
||
|
array_push($this->featureList, new Routeguide\Feature([
|
||
|
'name' => $feature->name,
|
||
|
'location' => new Routeguide\Point([
|
||
|
'latitude' => $feature->location->latitude,
|
||
|
'longitude' => $feature->location->longitude,
|
||
|
]),
|
||
|
]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function findFeature(\Routeguide\Point $point)
|
||
|
{
|
||
|
foreach ($this->featureList as $feature) {
|
||
|
$location = $feature->getLocation();
|
||
|
if (
|
||
|
$location->getLatitude() === $point->getLatitude()
|
||
|
&& $location->getLongitude() === $point->getLongitude()
|
||
|
) {
|
||
|
return $feature;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
// The formula is based on http://mathforum.org/library/drmath/view/51879.html
|
||
|
private function calculateDistance(
|
||
|
\Routeguide\Point $start,
|
||
|
\Routeguide\Point $end
|
||
|
) {
|
||
|
$toRadians = function (float $num) {
|
||
|
return $num * 3.1415926 / 180;
|
||
|
};
|
||
|
$coordFactor = 10000000.0;
|
||
|
$R = 6371000; // metres
|
||
|
|
||
|
$lat_1 = $start->getLatitude() / $coordFactor;
|
||
|
$lat_2 = $end->getLatitude() / $coordFactor;
|
||
|
$lon_1 = $start->getLongitude() / $coordFactor;
|
||
|
$lon_2 = $end->getLongitude() / $coordFactor;
|
||
|
$lat_rad_1 = $toRadians($lat_1);
|
||
|
$lat_rad_2 = $toRadians($lat_2);
|
||
|
$delta_lat_rad = $toRadians($lat_2 - $lat_1);
|
||
|
$delta_lon_rad = $toRadians($lon_2 - $lon_1);
|
||
|
|
||
|
$a = pow(sin($delta_lat_rad / 2), 2) +
|
||
|
cos($lat_rad_1) * cos($lat_rad_2) * pow(sin($delta_lon_rad / 2), 2);
|
||
|
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
||
|
|
||
|
return $R * $c;
|
||
|
}
|
||
|
|
||
|
public function GetFeature(
|
||
|
\Routeguide\Point $request,
|
||
|
\Grpc\ServerContext $serverContext
|
||
|
): ?\Routeguide\Feature {
|
||
|
$feature = $this->findFeature($request);
|
||
|
$notFoundFeature = new Routeguide\Feature([
|
||
|
'name' => '',
|
||
|
'location' => $request,
|
||
|
]);
|
||
|
return $feature ?? $notFoundFeature;
|
||
|
}
|
||
|
|
||
|
public function ListFeatures(
|
||
|
\Routeguide\Rectangle $request,
|
||
|
\Grpc\ServerCallWriter $writer,
|
||
|
\Grpc\ServerContext $serverContext
|
||
|
): void {
|
||
|
$lo = $request->getLo();
|
||
|
$hi = $request->getHi();
|
||
|
$left = min($lo->getLongitude(), $hi->getLongitude());
|
||
|
$right = max($lo->getLongitude(), $hi->getLongitude());
|
||
|
$top = max($lo->getLatitude(), $hi->getLatitude());
|
||
|
$bottom = min($lo->getLatitude(), $hi->getLatitude());
|
||
|
|
||
|
foreach ($this->featureList as $feature) {
|
||
|
$longitude = $feature->getLocation()->getLongitude();
|
||
|
$latitude = $feature->getLocation()->getLatitude();
|
||
|
if (
|
||
|
$longitude >= $left && $longitude <= $right
|
||
|
&& $latitude >= $bottom && $latitude <= $top
|
||
|
) {
|
||
|
$writer->write($feature);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$writer->finish();
|
||
|
}
|
||
|
|
||
|
public function RecordRoute(
|
||
|
\Grpc\ServerCallReader $reader,
|
||
|
\Grpc\ServerContext $serverContext
|
||
|
): ?\Routeguide\RouteSummary {
|
||
|
$point_count = 0;
|
||
|
$feature_count = 0;
|
||
|
$distance = 0;
|
||
|
$previous = null;
|
||
|
|
||
|
$start_time = time();
|
||
|
while ($point = $reader->read()) {
|
||
|
$point_count++;
|
||
|
$feature = $this->findFeature($point);
|
||
|
if ($feature) {
|
||
|
$feature_count++;
|
||
|
if ($previous) {
|
||
|
$distance += $this->calculateDistance($previous, $point);
|
||
|
}
|
||
|
$previous = $point;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$summary = new \Routeguide\RouteSummary();
|
||
|
$summary->setPointCount($point_count);
|
||
|
$summary->setFeatureCount($feature_count);
|
||
|
$summary->setDistance($distance);
|
||
|
$summary->setElapsedTime(time() - $start_time);
|
||
|
|
||
|
return $summary;
|
||
|
}
|
||
|
|
||
|
public function RouteChat(
|
||
|
\Grpc\ServerCallReader $reader,
|
||
|
\Grpc\ServerCallWriter $writer,
|
||
|
\Grpc\ServerContext $serverContext
|
||
|
): void {
|
||
|
while ($note = $reader->read()) {
|
||
|
foreach ($this->received_notes as $n) {
|
||
|
if (
|
||
|
$n->getLocation()->getLatitude() ===
|
||
|
$note->getLocation()->getLatitude()
|
||
|
&& $n->getLocation()->getLongitude() ===
|
||
|
$note->getLocation()->getLongitude()
|
||
|
) {
|
||
|
$writer->write($n);
|
||
|
}
|
||
|
}
|
||
|
array_push($this->received_notes, $note);
|
||
|
}
|
||
|
$writer->finish();
|
||
|
}
|
||
|
|
||
|
private $received_notes = [];
|
||
|
private $featureList = [];
|
||
|
}
|