Browse Source

Some GeoJSON works...

Maurits van der Schee 5 years ago
parent
commit
c61c1ae931
1 changed files with 229 additions and 0 deletions
  1. 229
    0
      api.php

+ 229
- 0
api.php View File

@@ -2779,6 +2779,61 @@ class ColumnController
2779 2779
     }
2780 2780
 }
2781 2781
 
2782
+// file: src/Tqdev/PhpCrudApi/Controller/GeoJsonController.php
2783
+
2784
+class GeoJsonController
2785
+{
2786
+    private $service;
2787
+    private $responder;
2788
+    private $geoJsonConverter;
2789
+
2790
+    public function __construct(Router $router, Responder $responder, GeoJsonService $service)
2791
+    {
2792
+        $router->register('GET', '/geojson/*', array($this, '_list'));
2793
+        $router->register('GET', '/geojson/*/*', array($this, 'read'));
2794
+        $this->service = $service;
2795
+        $this->responder = $responder;
2796
+    }
2797
+
2798
+    public function _list(ServerRequestInterface $request): ResponseInterface
2799
+    {
2800
+        $table = RequestUtils::getPathSegment($request, 2);
2801
+        $params = RequestUtils::getParams($request);
2802
+        if (!$this->service->hasTable($table)) {
2803
+            return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $table);
2804
+        }
2805
+        return $this->responder->success($this->service->_list($table, $params));
2806
+    }
2807
+
2808
+    public function read(ServerRequestInterface $request): ResponseInterface
2809
+    {
2810
+        $table = RequestUtils::getPathSegment($request, 2);
2811
+        if (!$this->service->hasTable($table)) {
2812
+            return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $table);
2813
+        }
2814
+        if ($this->service->getType($table) != 'table') {
2815
+            return $this->responder->error(ErrorCode::OPERATION_NOT_SUPPORTED, __FUNCTION__);
2816
+        }
2817
+        $id = RequestUtils::getPathSegment($request, 3);
2818
+        $params = RequestUtils::getParams($request);
2819
+        if (strpos($id, ',') !== false) {
2820
+            $ids = explode(',', $id);
2821
+            $result = [];
2822
+            for ($i = 0; $i < count($ids); $i++) {
2823
+                array_push($result, $this->service->read($table, $ids[$i], $params));
2824
+            }
2825
+            return $this->responder->success($result);
2826
+        } else {
2827
+            $response = $this->service->read($table, $id, $params);
2828
+            if ($response === null) {
2829
+                return $this->responder->error(ErrorCode::RECORD_NOT_FOUND, $id);
2830
+            }
2831
+            return $this->responder->success($response);
2832
+        }
2833
+    }
2834
+
2835
+}
2836
+
2782 2837
 // file: src/Tqdev/PhpCrudApi/Controller/OpenApiController.php
2783 2838
 
2784 2839
 class OpenApiController
@@ -4417,6 +4472,175 @@ class TypeConverter
4417 4472
     }
4418 4473
 }
4419 4474
 
4475
+// file: src/Tqdev/PhpCrudApi/GeoJson/Feature.php
4476
+
4477
+class Feature implements \JsonSerializable
4478
+{
4479
+    private $properties;
4480
+    private $geometry;
4481
+
4482
+    public function __construct(array $properties, Geometry $geometry)
4483
+    {
4484
+        $this->properties = $properties;
4485
+        $this->geometry = $geometry;
4486
+    }
4487
+
4488
+    public function serialize()
4489
+    {
4490
+        return [
4491
+            'type' => 'Feature',
4492
+            'properties' => $this->properties,
4493
+            'geometry' => $this->geometry,
4494
+        ];
4495
+    }
4496
+
4497
+    public function jsonSerialize()
4498
+    {
4499
+        return $this->serialize();
4500
+    }
4501
+}
4502
+
4503
+// file: src/Tqdev/PhpCrudApi/GeoJson/FeatureCollection.php
4504
+
4505
+class FeatureCollection implements \JsonSerializable
4506
+{
4507
+    private $features;
4508
+
4509
+    public function __construct(array $features)
4510
+    {
4511
+        $this->features = $features;
4512
+    }
4513
+
4514
+    public static function fromListDocument(ListDocument $records, string $geometryColumnName): FeatureCollection
4515
+    {
4516
+        $features = array();
4517
+        foreach ($records->getRecords() as $record) {
4518
+            if (isset($record[$geometryColumnName])) {
4519
+                $geometry = Geometry::fromWkt($record[$geometryColumnName]);
4520
+                unset($record[$geometryColumnName]);
4521
+                $features[] = new Feature($record, $geometry);
4522
+            }
4523
+        }
4524
+        return new FeatureCollection($features);
4525
+    }
4526
+
4527
+    public function serialize()
4528
+    {
4529
+        return [
4530
+            'type' => 'FeatureCollection',
4531
+            'features' => $this->features,
4532
+        ];
4533
+    }
4534
+
4535
+    public function jsonSerialize()
4536
+    {
4537
+        return $this->serialize();
4538
+    }
4539
+}
4540
+
4541
+// file: src/Tqdev/PhpCrudApi/GeoJson/GeoJsonService.php
4542
+
4543
+class GeoJsonService
4544
+{
4545
+    private $reflection;
4546
+    private $records;
4547
+
4548
+    public function __construct(ReflectionService $reflection, RecordService $records)
4549
+    {
4550
+        $this->reflection = $reflection;
4551
+        $this->records = $records;
4552
+    }
4553
+
4554
+    public function hasTable(string $table): bool
4555
+    {
4556
+        return $this->reflection->hasTable($table);
4557
+    }
4558
+
4559
+    private function getGeometryColumnName(string $tableName, string $geometryParam): string
4560
+    {
4561
+        $table = $this->reflection->getTable($tableName);
4562
+        foreach ($table->getColumnNames() as $columnName) {
4563
+            if ($geometryParam && $geometryParam != $columnName) {
4564
+                continue;
4565
+            }
4566
+            $column = $table->getColumn($columnName);
4567
+            if ($column->isGeometry()) {
4568
+                return $columnName;
4569
+            }
4570
+        }
4571
+        return "";
4572
+    }
4573
+
4574
+    public function _list(string $tableName, array $params): FeatureCollection
4575
+    {
4576
+        $geometryParam = isset($params['geometry']) ? $params['geometry'] : '';
4577
+        $geometryColumnName = $this->getGeometryColumnName($tableName, $geometryParam);
4578
+        $records = $this->records->_list($tableName, $params);
4579
+        return FeatureCollection::fromListDocument($records, $geometryColumnName);
4580
+    }
4581
+
4582
+    public function read(string $tableName, string $id, array $params) /*: ?object*/
4583
+    {
4584
+        return $this->records->read($tableName, $id, $params);
4585
+    }
4586
+}
4587
+
4588
+// file: src/Tqdev/PhpCrudApi/GeoJson/Geometry.php
4589
+
4590
+class Geometry implements \JsonSerializable
4591
+{
4592
+    private $type;
4593
+    private $geometry;
4594
+
4595
+    public static $types = [
4596
+        "Point",
4597
+        "MultiPoint",
4598
+        "LineString",
4599
+        "MultiLineString",
4600
+        "Polygon",
4601
+        "MultiPolygon",
4602
+        "GeometryCollection",
4603
+    ];
4604
+
4605
+    public function __construct(string $type, array $coordinates)
4606
+    {
4607
+        $this->type = $type;
4608
+        $this->coordinates = $coordinates;
4609
+    }
4610
+
4611
+    public static function fromWkt(string $wkt): Geometry
4612
+    {
4613
+        $bracket = strpos($wkt, '(');
4614
+        $type = strtoupper(trim(substr($wkt, 0, $bracket)));
4615
+        foreach (Geometry::$types as $typeName) {
4616
+            if (strtoupper($typeName) == $type) {
4617
+                $type = $typeName;
4618
+            }
4619
+        }
4620
+        $coordinates = substr($wkt, $bracket);
4621
+        $coordinates = preg_replace('|([0-9\-\.]+ )+([0-9\-\.]+)|', '[\1\2]', $coordinates);
4622
+        $coordinates = str_replace(['(', ')', ' '], ['[', ']', ','], $coordinates);
4623
+        $coordinates = json_decode($coordinates);
4624
+        if ($type == 'Point') {
4625
+            $coordinates = $coordinates[0];
4626
+        }
4627
+        return new Geometry($type, $coordinates);
4628
+    }
4629
+
4630
+    public function serialize()
4631
+    {
4632
+        return [
4633
+            'type' => $this->type,
4634
+            'coordinates' => $this->coordinates,
4635
+        ];
4636
+    }
4637
+
4638
+    public function jsonSerialize()
4639
+    {
4640
+        return $this->serialize();
4641
+    }
4642
+}
4643
+
4420 4644
 // file: src/Tqdev/PhpCrudApi/Middleware/Base/Middleware.php
4421 4645
 
4422 4646
 abstract class Middleware implements MiddlewareInterface
@@ -7031,6 +7255,11 @@ class Api implements RequestHandlerInterface
7031 7255
                     $openApi = new OpenApiService($reflection, $config->getOpenApiBase());
7032 7256
                     new OpenApiController($router, $responder, $openApi);
7033 7257
                     break;
7258
+                case 'geojson':
7259
+                    $records = new RecordService($db, $reflection);
7260
+                    $geoJson = new GeoJsonService($reflection, $records);
7261
+                    new GeoJsonController($router, $responder, $geoJson);
7262
+                    break;
7034 7263
             }
7035 7264
         }
7036 7265
         $this->router = $router;

Loading…
Cancel
Save