Advertisement
Guest User

Untitled

a guest
Aug 28th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.92 KB | None | 0 0
  1. <?php
  2.  
  3. class GeoJSON
  4. {
  5. public function __construct(string $geojson)
  6. {
  7. $this->_struct = json_decode($geojson);
  8. }
  9.  
  10. public static function fromString(string $geojson)
  11. {
  12. return new static($geojson);
  13. }
  14.  
  15. public static function fromFile(string $geojson_file)
  16. {
  17. return new static(file_get_contents($geojson_file));
  18. }
  19.  
  20. public function parse()
  21. {
  22. if ($this->_struct->type == 'Feature') {
  23. return new Feature($this->_struct);
  24. }
  25.  
  26. if ($this->_struct->type == 'FeatureCollection') {
  27. return new FeatureCollection($this->_struct);
  28. }
  29.  
  30. throw Exception('Invalid GeoJSON');
  31. }
  32. }
  33.  
  34. class FeatureCollection
  35. {
  36. public function __construct($struct)
  37. {
  38. $this->_struct = $struct;
  39. $this->validate();
  40. }
  41.  
  42. public function validate()
  43. {
  44. assert(isset($this->_struct->features), new Exception('Missing feature collection'));
  45. }
  46.  
  47. public function isCollection()
  48. {
  49. return true;
  50. }
  51.  
  52. public function features()
  53. {
  54. $features = [];
  55.  
  56. foreach ($this->_struct->features as $feature) {
  57. $features[] = new Feature($feature);
  58. }
  59.  
  60. return $features;
  61. }
  62. }
  63.  
  64. class Feature
  65. {
  66. public function __construct($struct)
  67. {
  68. $this->_struct = $struct;
  69. $this->validate();
  70. }
  71.  
  72. public function validate()
  73. {
  74. assert(isset($this->_struct->geometry), new Exception('Missing feature geometry'));
  75. assert(isset($this->_struct->properties), new Exception('Missing feature properties'));
  76. }
  77.  
  78. public function isCollection()
  79. {
  80. return False;
  81. }
  82.  
  83. public function geometry()
  84. {
  85. return new Geometry($this->_struct->geometry);
  86. }
  87.  
  88. public function properties()
  89. {
  90. return $this->_struct->properties;
  91. }
  92. }
  93.  
  94. class Geometry
  95. {
  96. public function __construct($struct)
  97. {
  98. $this->_struct = $struct;
  99. $this->validate();
  100. }
  101.  
  102. public function validate()
  103. {
  104. assert(isset($this->_struct->type), new Exception('Missing geometry type'));
  105. assert(in_array($this->_struct->type, ['Point', 'Polygon']), new Exception('Unsupported geometry type'));
  106. assert(isset($this->_struct->coordinates), new Exception('Missing geometry coordinates'));
  107. }
  108.  
  109. public function type()
  110. {
  111. return $this->_struct->type;
  112. }
  113.  
  114. public function coordinates()
  115. {
  116. return $this->_struct->coordinates;
  117. }
  118.  
  119. public function parse()
  120. {
  121. if ($this->type() == 'Point') {
  122. list($x, $y) = $this->_struct->coordinates;
  123. return new Point($this->_struct->coordinates);
  124. }
  125.  
  126. if ($this->type() == 'Polygon') {
  127. return new Polygon($this->_struct->coordinates[0]);
  128. }
  129.  
  130. throw new Exception('Unsupported geometry type');
  131. }
  132. }
  133.  
  134. class Point
  135. {
  136. private $_x;
  137. private $_y;
  138.  
  139. public function __construct(float $x, float $y)
  140. {
  141. $this->setLongitude($x);
  142. $this->setLatitude($y);
  143. }
  144.  
  145. public function latitude()
  146. {
  147. return $this->_y;
  148. }
  149.  
  150. public function longitude()
  151. {
  152. return $this->_x;
  153. }
  154.  
  155. public function setLatitude(float $y)
  156. {
  157. assert($y >= -90 && $y <= 90, new Exception('Invalid latitude degree'));
  158.  
  159. $this->_y = $y;
  160. }
  161.  
  162. public function setLongitude(float $x)
  163. {
  164. assert($x >= -180 && $x <= 180, new Exception('Invalid longitude degree'));
  165.  
  166. $this->_x = $x;
  167. }
  168. }
  169.  
  170. class Polygon
  171. {
  172. private $_points;
  173.  
  174. public function __construct(array $points = [])
  175. {
  176. $this->addPoints($points);
  177. }
  178.  
  179. public function addPoints(array $points)
  180. {
  181. foreach ($points as $point) {
  182. list($x, $y) = $point;
  183. $this->addPoint(new Point($x, $y));
  184. }
  185. }
  186.  
  187. public function addPoint(Point $point)
  188. {
  189. $this->_points[] = $point;
  190. }
  191.  
  192. public function contains(Point $point)
  193. {
  194. $contains = false;
  195. $n_points = count($this->_points);
  196.  
  197. for ($i = 0, $j = $n_points - 1; $i < $n_points; $j = $i++) {
  198. $i_point = $this->_points[$i];
  199. $j_point = $this->_points[$j];
  200.  
  201. if ((($i_point->longitude() > $point->longitude()) != ($j_point->longitude() > $point->longitude()))
  202. && ($point->latitude() < ($j_point->latitude() - $i_point->latitude()) * ($point->longitude() - $i_point->longitude()) / ($j_point->longitude() - $i_point->longitude()) + $i_point->latitude())) {
  203. $contains = !$contains;
  204. }
  205. }
  206.  
  207. return $contains;
  208. }
  209. }
  210.  
  211. $raw_geojson = '{
  212. "type": "FeatureCollection",
  213. "features": [
  214. {
  215. "type": "Feature",
  216. "geometry": {
  217. "type": "Polygon",
  218. "coordinates": [
  219. [
  220. [
  221. -47.498998045921326,
  222. -23.533586090311893
  223. ],
  224. [
  225. -47.49819874763489,
  226. -23.532789333203414
  227. ],
  228. [
  229. -47.49783396720886,
  230. -23.533109020277173
  231. ],
  232. [
  233. -47.49861717224121,
  234. -23.533905775449583
  235. ],
  236. [
  237. -47.498998045921326,
  238. -23.533586090311893
  239. ]
  240. ]
  241. ]
  242. },
  243. "properties": {
  244. }
  245. }
  246. ]
  247. }';
  248.  
  249. $feature = GeoJSON::fromString($raw_geojson)->parse();
  250.  
  251. function polygon_contains($feature, $point)
  252. {
  253. if (!$feature->isCollection()) {
  254. return $feature instanceof Polygon && $geometry->contains($point);
  255. }
  256.  
  257. foreach ($feature->features() as $feature) {
  258. $polygon = $feature->geometry()->parse();
  259.  
  260. if ($polygon instanceof Polygon && $polygon->contains($point)) {
  261. return True;
  262. }
  263. }
  264.  
  265. return False;
  266. }
  267.  
  268. var_dump(polygon_contains($feature, new Point(-47.0869358, -22.9075211))); // false
  269. var_dump(polygon_contains($feature, new Point(-47.49847769737243, -23.533305750397986))); // true
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement