api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
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.

GeoJsonService.php 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. namespace Tqdev\PhpCrudApi\GeoJson;
  3. use Tqdev\PhpCrudApi\Column\ReflectionService;
  4. use Tqdev\PhpCrudApi\GeoJson\FeatureCollection;
  5. use Tqdev\PhpCrudApi\Record\RecordService;
  6. class GeoJsonService
  7. {
  8. private $reflection;
  9. private $records;
  10. public function __construct(ReflectionService $reflection, RecordService $records)
  11. {
  12. $this->reflection = $reflection;
  13. $this->records = $records;
  14. }
  15. public function hasTable(string $table): bool
  16. {
  17. return $this->reflection->hasTable($table);
  18. }
  19. public function getType(string $table): string
  20. {
  21. return $this->reflection->getType($table);
  22. }
  23. private function getGeometryColumnName(string $tableName, array &$params): string
  24. {
  25. $geometryParam = isset($params['geometry']) ? $params['geometry'][0] : '';
  26. $table = $this->reflection->getTable($tableName);
  27. $geometryColumnName = '';
  28. foreach ($table->getColumnNames() as $columnName) {
  29. if ($geometryParam && $geometryParam != $columnName) {
  30. continue;
  31. }
  32. $column = $table->getColumn($columnName);
  33. if ($column->isGeometry()) {
  34. $geometryColumnName = $columnName;
  35. break;
  36. }
  37. }
  38. if ($geometryColumnName) {
  39. $params['mandatory'][] = $tableName . "." . $geometryColumnName;
  40. }
  41. return $geometryColumnName;
  42. }
  43. private function setBoudingBoxFilter(string $geometryColumnName, array &$params)
  44. {
  45. $boundingBox = isset($params['bbox']) ? $params['bbox'][0] : '';
  46. if ($boundingBox) {
  47. $c = explode(',', $boundingBox);
  48. if (!isset($params['filter'])) {
  49. $params['filter'] = array();
  50. }
  51. $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]))";
  52. }
  53. $tile = isset($params['tile']) ? $params['tile'][0] : '';
  54. if ($tile) {
  55. $zxy = explode(',', $tile);
  56. if (count($zxy) == 3) {
  57. list($z, $x, $y) = $zxy;
  58. $c = array();
  59. $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x, $y));
  60. $c = array_merge($c, $this->convertTileToLatLonOfUpperLeftCorner($z, $x + 1, $y + 1));
  61. $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]))";
  62. }
  63. }
  64. }
  65. private function convertTileToLatLonOfUpperLeftCorner($z, $x, $y): array
  66. {
  67. $n = pow(2, $z);
  68. $lon = $x / $n * 360.0 - 180.0;
  69. $lat = rad2deg(atan(sinh(pi() * (1 - 2 * $y / $n))));
  70. return [$lon, $lat];
  71. }
  72. private function convertRecordToFeature(/*object*/$record, string $primaryKeyColumnName, string $geometryColumnName)
  73. {
  74. $id = null;
  75. if ($primaryKeyColumnName) {
  76. $id = $record[$primaryKeyColumnName];
  77. }
  78. $geometry = null;
  79. if (isset($record[$geometryColumnName])) {
  80. $geometry = Geometry::fromWkt($record[$geometryColumnName]);
  81. }
  82. $properties = array_diff_key($record, [$primaryKeyColumnName => true, $geometryColumnName => true]);
  83. return new Feature($id, $properties, $geometry);
  84. }
  85. private function getPrimaryKeyColumnName(string $tableName, array &$params): string
  86. {
  87. $primaryKeyColumn = $this->reflection->getTable($tableName)->getPk();
  88. if (!$primaryKeyColumn) {
  89. return '';
  90. }
  91. $primaryKeyColumnName = $primaryKeyColumn->getName();
  92. $params['mandatory'][] = $tableName . "." . $primaryKeyColumnName;
  93. return $primaryKeyColumnName;
  94. }
  95. public function _list(string $tableName, array $params): FeatureCollection
  96. {
  97. $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
  98. $this->setBoudingBoxFilter($geometryColumnName, $params);
  99. $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
  100. $records = $this->records->_list($tableName, $params);
  101. $features = array();
  102. foreach ($records->getRecords() as $record) {
  103. $features[] = $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
  104. }
  105. return new FeatureCollection($features, $records->getResults());
  106. }
  107. public function read(string $tableName, string $id, array $params): Feature
  108. {
  109. $geometryColumnName = $this->getGeometryColumnName($tableName, $params);
  110. $primaryKeyColumnName = $this->getPrimaryKeyColumnName($tableName, $params);
  111. $record = $this->records->read($tableName, $id, $params);
  112. return $this->convertRecordToFeature($record, $primaryKeyColumnName, $geometryColumnName);
  113. }
  114. }