123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- <?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 = [];
- }
|