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.
182 lines
5.9 KiB
182 lines
5.9 KiB
<?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 = []; |
|
}
|
|
|