Browse Source

support tiles in GeoJSON

Maurits van der Schee 6 years ago
parent
commit
573be5f9e4
3 changed files with 88 additions and 34 deletions
  1. 44
    17
      api.php
  2. 6
    3
      src/Tqdev/PhpCrudApi/GeoJson/Feature.php
  3. 38
    14
      src/Tqdev/PhpCrudApi/GeoJson/GeoJsonService.php

+ 44
- 17
api.php View File

@@ -4477,22 +4477,25 @@ class TypeConverter
4477 4477
 
4478 4478
 class Feature implements \JsonSerializable
4479 4479
 {
4480
+    private $id;
4480 4481
     private $properties;
4481 4482
     private $geometry;
4482 4483
 
4483
-    public function __construct(array $properties, /*?Geometry*/ $geometry)
4484
+    public function __construct(string $id, array $properties, /*?Geometry*/ $geometry)
4484 4485
     {
4486
+        $this->id = $id;
4485 4487
         $this->properties = $properties;
4486 4488
         $this->geometry = $geometry;
4487 4489
     }
4488 4490
 
4489 4491
     public function serialize()
4490 4492
     {
4491
-        return [
4493
+        return array_filter([
4492 4494
             'type' => 'Feature',
4495
+            'id' => $this->id,
4493 4496
             'properties' => $this->properties,
4494 4497
             'geometry' => $this->geometry,
4495
-        ];
4498
+        ]);
4496 4499
     }
4497 4500
 
4498 4501
     public function jsonSerialize()
@@ -4586,38 +4589,61 @@ class GeoJsonService
4586 4589
             }
4587 4590
             $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
4588 4591
         }
4589
-        /*
4590 4592
         $tile = isset($params['tile']) ? $params['tile'][0] : '';
4591 4593
         if ($tile) {
4592
-            
4593
-            $n = pow(2, $zoom);
4594
-            $lon_deg = $xtile / $n * 360.0 - 180.0;
4595
-            $lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));
4596
-
4597
-            calculates upperleft corner
4594
+            $zxy = explode(',', $tile);
4595
+            if (count($zxy) == 3) {
4596
+                list($z, $x, $y) = $zxy;
4597
+                $c = array();
4598
+                $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x, $y));
4599
+                $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x + 1, $y + 1));
4600
+                $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
4601
+            }
4602
+        }
4603
+    }
4598 4604
 
4599
-            $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
4600
-        }*/
4605
+    private function convertTileToLatLonOfUpperLeftCorner($z, $x, $y): array
4606
+    {
4607
+        $n = pow(2, $z);
4608
+        $lon = $x / $n * 360.0 - 180.0;
4609
+        $lat = rad2deg(atan(sinh(pi() * (1 - 2 * $y / $n))));
4610
+        return [$lon, $lat];
4601 4611
     }
4602 4612
 
4603
-    private function convertRecordToFeature( /*object*/$record, string $geometryColumnName)
4613
+    private function convertRecordToFeature( /*object*/$record, string $primaryKeyColumnName, string $geometryColumnName)
4604 4614
     {
4615
+        $id = '';
4616
+        if ($primaryKeyColumnName) {
4617
+            $id = $record[$primaryKeyColumnName];
4618
+        }
4605 4619
         $geometry = null;
4606 4620
         if (isset($record[$geometryColumnName])) {
4607 4621
             $geometry = Geometry::fromWkt($record[$geometryColumnName]);
4608 4622
         }
4609
-        $properties = array_diff_key($record, [$geometryColumnName => true]);
4610
-        return new Feature($properties, $geometry);
4623
+        $properties = array_diff_key($record, [$primaryKeyColumnName => true, $geometryColumnName => true]);
4624
+        return new Feature($id, $properties, $geometry);
4625
+    }
4626
+
4627
+    private function getPrimaryKeyColumnName(string $tableName, array &$params): string
4628
+    {
4629
+        $primaryKeyColumn = $this->reflection->getTable($tableName)->getPk();
4630
+        if (!$primaryKeyColumn) {
4631
+            return '';
4632
+        }
4633
+        $primaryKeyColumnName = $primaryKeyColumn->getName();
4634
+        $params['mandatory'][] = $tableName . "." . $primaryKeyColumnName;
4635
+        return $primaryKeyColumnName;
4611 4636
     }
4612 4637
 
4613 4638
     public function _list(string $tableName, array $params): FeatureCollection
4614 4639
     {
4615 4640
         $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
4616 4641
         $this->setBoudingBoxFilter($geometryColumnName, $params);
4642
+        $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
4617 4643
         $records = $this->records->_list($tableName, $params);
4618 4644
         $features = array();
4619 4645
         foreach ($records->getRecords() as $record) {
4620
-            $features[] = $this->convertRecordToFeature($record, $geometryColumnName);
4646
+            $features[] = $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
4621 4647
         }
4622 4648
         return new FeatureCollection($features, $records->getResults());
4623 4649
     }
@@ -4626,8 +4652,9 @@ class GeoJsonService
4626 4652
     {
4627 4653
         $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
4628 4654
         $this->setBoudingBoxFilter($geometryColumnName, $params);
4655
+        $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
4629 4656
         $record = $this->records->read($tableName, $id, $params);
4630
-        return $this->convertRecordToFeature($record, $geometryColumnName);
4657
+        return $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
4631 4658
     }
4632 4659
 }
4633 4660
 

+ 6
- 3
src/Tqdev/PhpCrudApi/GeoJson/Feature.php View File

@@ -3,22 +3,25 @@ namespace Tqdev\PhpCrudApi\GeoJson;
3 3
 
4 4
 class Feature implements \JsonSerializable
5 5
 {
6
+    private $id;
6 7
     private $properties;
7 8
     private $geometry;
8 9
 
9
-    public function __construct(array $properties, /*?Geometry*/ $geometry)
10
+    public function __construct(string $id, array $properties, /*?Geometry*/ $geometry)
10 11
     {
12
+        $this->id = $id;
11 13
         $this->properties = $properties;
12 14
         $this->geometry = $geometry;
13 15
     }
14 16
 
15 17
     public function serialize()
16 18
     {
17
-        return [
19
+        return array_filter([
18 20
             'type' => 'Feature',
21
+            'id' => $this->id,
19 22
             'properties' => $this->properties,
20 23
             'geometry' => $this->geometry,
21
-        ];
24
+        ]);
22 25
     }
23 26
 
24 27
     public function jsonSerialize()

+ 38
- 14
src/Tqdev/PhpCrudApi/GeoJson/GeoJsonService.php View File

@@ -57,38 +57,61 @@ class GeoJsonService
57 57
             }
58 58
             $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
59 59
         }
60
-        /*
61 60
         $tile = isset($params['tile']) ? $params['tile'][0] : '';
62 61
         if ($tile) {
63
-            
64
-            $n = pow(2, $zoom);
65
-            $lon_deg = $xtile / $n * 360.0 - 180.0;
66
-            $lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));
67
-
68
-            calculates upperleft corner
62
+            $zxy = explode(',', $tile);
63
+            if (count($zxy) == 3) {
64
+                list($z, $x, $y) = $zxy;
65
+                $c = array();
66
+                $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x, $y));
67
+                $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x + 1, $y + 1));
68
+                $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
69
+            }
70
+        }
71
+    }
69 72
 
70
-            $params['filter'][] = "$geometryColumnName,sin,POLYGON(($c[0] $c[1],$c[2] $c[1],$c[2] $c[3],$c[0] $c[3],$c[0] $c[1]))";
71
-        }*/
73
+    private function convertTileToLatLonOfUpperLeftCorner($z, $x, $y): array
74
+    {
75
+        $n = pow(2, $z);
76
+        $lon = $x / $n * 360.0 - 180.0;
77
+        $lat = rad2deg(atan(sinh(pi() * (1 - 2 * $y / $n))));
78
+        return [$lon, $lat];
72 79
     }
73 80
 
74
-    private function convertRecordToFeature( /*object*/$record, string $geometryColumnName)
81
+    private function convertRecordToFeature( /*object*/$record, string $primaryKeyColumnName, string $geometryColumnName)
75 82
     {
83
+        $id = '';
84
+        if ($primaryKeyColumnName) {
85
+            $id = $record[$primaryKeyColumnName];
86
+        }
76 87
         $geometry = null;
77 88
         if (isset($record[$geometryColumnName])) {
78 89
             $geometry = Geometry::fromWkt($record[$geometryColumnName]);
79 90
         }
80
-        $properties = array_diff_key($record, [$geometryColumnName => true]);
81
-        return new Feature($properties, $geometry);
91
+        $properties = array_diff_key($record, [$primaryKeyColumnName => true, $geometryColumnName => true]);
92
+        return new Feature($id, $properties, $geometry);
93
+    }
94
+
95
+    private function getPrimaryKeyColumnName(string $tableName, array &$params): string
96
+    {
97
+        $primaryKeyColumn = $this->reflection->getTable($tableName)->getPk();
98
+        if (!$primaryKeyColumn) {
99
+            return '';
100
+        }
101
+        $primaryKeyColumnName = $primaryKeyColumn->getName();
102
+        $params['mandatory'][] = $tableName . "." . $primaryKeyColumnName;
103
+        return $primaryKeyColumnName;
82 104
     }
83 105
 
84 106
     public function _list(string $tableName, array $params): FeatureCollection
85 107
     {
86 108
         $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
87 109
         $this->setBoudingBoxFilter($geometryColumnName, $params);
110
+        $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
88 111
         $records = $this->records->_list($tableName, $params);
89 112
         $features = array();
90 113
         foreach ($records->getRecords() as $record) {
91
-            $features[] = $this->convertRecordToFeature($record, $geometryColumnName);
114
+            $features[] = $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
92 115
         }
93 116
         return new FeatureCollection($features, $records->getResults());
94 117
     }
@@ -97,7 +120,8 @@ class GeoJsonService
97 120
     {
98 121
         $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
99 122
         $this->setBoudingBoxFilter($geometryColumnName, $params);
123
+        $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
100 124
         $record = $this->records->read($tableName, $id, $params);
101
-        return $this->convertRecordToFeature($record, $geometryColumnName);
125
+        return $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
102 126
     }
103 127
 }

Loading…
Cancel
Save