Skip to content

Commit

Permalink
Merge pull request #421 from tdt/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
coreation authored Dec 24, 2016
2 parents ef111d8 + 72aec5e commit d800368
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 241 deletions.
25 changes: 12 additions & 13 deletions app/Tdt/Core/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @license AGPLv3
* @author Jan Vansteenlandt <jan@okfn.be>
*/
abstract class ApiController extends \Controller
abstract class ApiController extends Controller
{

protected $definition;
Expand All @@ -23,27 +23,26 @@ public function __construct(DefinitionRepositoryInterface $definition)

public function handle($uri)
{

$uri = ltrim($uri, '/');

// Delegate the request based on the used http method
$method = \Request::getMethod();

switch ($method) {
case "PUT":
case 'PUT':
return $this->put($uri);
break;
case "GET":
case 'GET':
return $this->get($uri);
break;
case "POST":
case "PATCH":
case 'POST':
case 'PATCH':
return $this->patch($uri);
break;
case "DELETE":
case 'DELETE':
return $this->delete($uri);
break;
case "HEAD":
case 'HEAD':
return $this->head($uri);
break;
default:
Expand All @@ -55,26 +54,26 @@ public function handle($uri)

public function get($uri)
{
\App::abort(405, "The HTTP method GET is not supported by this resource.");
\App::abort(405, 'The HTTP method GET is not supported by this resource.');
}

public function put($uri)
{
\App::abort(405, "The HTTP method PUT is not supported by this resource.");
\App::abort(405, 'The HTTP method PUT is not supported by this resource.');
}

public function patch($uri)
{
\App::abort(405, "The HTTP method PATCH is not supported by this resource.");
\App::abort(405, 'The HTTP method PATCH is not supported by this resource.');
}

public function head($uri)
{
\App::abort(405, "The HTTP method HEAD is not supported by this resource.");
\App::abort(405, 'The HTTP method HEAD is not supported by this resource.');
}

public function delete($uri)
{
\App::abort(405, "The HTTP method DELETE is not supported by this resource.");
\App::abort(405, 'The HTTP method DELETE is not supported by this resource.');
}
}
43 changes: 40 additions & 3 deletions app/Tdt/Core/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @license AGPLv3
* @author Michiel Vancoillie <michiel@okfn.be>
*/
class BaseController extends \Controller
class BaseController extends Controller
{
/*
* Handles all core requests
Expand All @@ -29,7 +29,10 @@ public function handleRequest($uri)
$controller = 'Tdt\\Core\\Definitions\\DiscoveryController';
break;
case 'api':
switch (\Request::segment(2)) {
// Allow for content negotiation for api endpoints
list($apiResource, $extension) = self::processURI(\Request::segment(2));

switch ($apiResource) {
case 'definitions':
// Definitions request
$controller = 'Tdt\\Core\\Definitions\\DefinitionController';
Expand Down Expand Up @@ -74,7 +77,7 @@ public function handleRequest($uri)
$uri = str_replace('api/keywords', '', $uri);
break;
default:
\App::abort(404, "Page not found.");
\App::abort(404, 'Page not found.');
break;
}

Expand Down Expand Up @@ -107,4 +110,38 @@ public function handleRequest($uri)
return $response;
}
}

/**
* Process the URI and return the extension (=format) and the resource identifier URI
*
* @param string $uri The URI that has been passed
* @return array
*/
public static function processURI($uri)
{
$dot_position = strrpos($uri, '.');

if (! $dot_position) {
return array($uri, null);
}

// If a dot has been found, do a couple
// of checks to find out if it introduces a formatter
$uri_parts = explode('.', $uri);

$possible_extension = strtoupper(array_pop($uri_parts));

$uri = implode('.', $uri_parts);

$formatter_class = 'Tdt\\Core\\Formatters\\' . $possible_extension . 'Formatter';

if (! class_exists($formatter_class)) {
// Re-attach the dot with the latter part of the uri
$uri .= '.' . strtolower($possible_extension);

return array($uri, null);
}

return array($uri, strtolower($possible_extension));
}
}
40 changes: 40 additions & 0 deletions app/Tdt/Core/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tdt\Core;

class Controller extends \Controller
{
/**
* Process the URI and return the extension (=format) and the resource identifier URI
*
* @param string $uri The URI that has been passed
* @return array
*/
public static function processURI($uri)
{
$dot_position = strrpos($uri, '.');

if (! $dot_position) {
return array($uri, null);
}

// If a dot has been found, do a couple
// of checks to find out if it introduces a formatter
$uri_parts = explode('.', $uri);

$possible_extension = strtoupper(array_pop($uri_parts));

$uri = implode('.', $uri_parts);

$formatter_class = 'Tdt\\Core\\Formatters\\' . $possible_extension . 'Formatter';

if (! class_exists($formatter_class)) {
// Re-attach the dot with the latter part of the uri
$uri .= '.' . strtolower($possible_extension);

return array($uri, null);
}

return array($uri, strtolower($possible_extension));
}
}
68 changes: 35 additions & 33 deletions app/Tdt/Core/DataControllers/SHPController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Tdt\Core\Pager;
use Tdt\Core\Repositories\Interfaces\TabularColumnsRepositoryInterface;
use Tdt\Core\Repositories\Interfaces\GeoPropertyRepositoryInterface;
use muka\ShapeReader\ShapeReader;
use ShapeFile\ShapeFile;
use Tdt\Core\Repositories\Interfaces\GeoprojectionRepositoryInterface;

class SHPController extends ADataController
Expand Down Expand Up @@ -98,8 +98,6 @@ public function readData($source_definition, $rest_parameters = array())
$arrayOfRowObjects = array();

// Prepare the options to read the SHP file
$options = array('noparts' => false);

$is_url = (substr($uri, 0, 4) == "http");

// If the shape files are located on an HTTP address, fetch them and store them locally
Expand All @@ -112,34 +110,36 @@ public function readData($source_definition, $rest_parameters = array())
file_put_contents($tmp_file . ".shx", file_get_contents(substr($uri, 0, strlen($uri) - 4) . ".shx"));

// Along this file the class will use file.shx and file.dbf
$shp = new ShapeReader($tmp_file . ".shp", $options);
$shape_file = new ShapeFile($tmp_file . ".shp");
} else {
$shp = new ShapeReader($uri, $options); // along this file the class will use file.shx and file.dbf
$shape_file = new ShapeFile($uri); // along this file the class will use file.shx and file.dbf
}

// Keep track of the total amount of rows
$total_rows = 0;

// Get the shape records in the binary file
while ($record = $shp->getNext()) {
while ($record = $shape_file->getRecord()) {
if ($offset <= $total_rows && $offset + $limit > $total_rows) {
// Every shape record is parsed as an anonymous object with the properties attached to it
$rowobject = new \stdClass();

// Get the dBASE data
$dbf_data = $record->getDbfData();
$dbf_data = $record['dbf'];

foreach ($dbf_data as $property => $value) {
$property_alias = $columns[$property];
$property = trim($property);
$property_alias = $columns[$property];
$rowobject->$property_alias = trim($value);
if (array_key_exists($property, $columns)) {
$property_alias = $columns[$property];
$property = trim($property);
$property_alias = $columns[$property];
$rowobject->$property_alias = trim($value);
}
}

// Read the shape data
$shp_data = $record->getShpData();
$shp_data = $record['shp'];

$shape_type = self::$RECORD_TYPES[$record->getTypeCode()];
$shape_type = self::$RECORD_TYPES[$shape_file->getShapeType()];

// Get the projection code
$projection = $this->projections->getByCode($this->epsg);
Expand All @@ -154,8 +154,6 @@ public function readData($source_definition, $rest_parameters = array())
$this->projSrc = new Proj('EPSG:' . $this->epsg, $this->proj4);
$this->projDest = new Proj('EPSG:4326', $this->proj4);

$geometry = [];

switch (strtolower($shape_type)) {
case 'point':
$point = $this->parsePoint($shp_data);
Expand Down Expand Up @@ -326,11 +324,14 @@ private function parsePolygon($shp_data)
foreach ($shp_data['parts'] as $part) {
$points = array();

foreach ($part['points'] as $point) {
// We don't support multi-ring polygon
$first_ring_points = array_shift($part['rings']);

foreach ($first_ring_points['points'] as $point) {
$x = $point['x'];
$y = $point['y'];

// Translate the coordinates to WSG84 geo coordinates
// Translate the coordinates to WSG84 geo coordinates
if (!empty($this->epsg)) {
$pointSrc = new Point($x, $y);

Expand All @@ -341,6 +342,7 @@ private function parsePolygon($shp_data)

$points[] = $x . ',' . $y;
}

array_push($parts, implode(" ", $points));
}

Expand All @@ -354,7 +356,10 @@ private function parsePolygonZ($shp_data)
foreach ($shp_data['parts'] as $part) {
$points = array();

foreach ($part['points'] as $point) {
// We don't support multi-ring polygon
$first_ring_points = array_shift($part['rings']);

foreach ($first_ring_points['points'] as $point) {
$x = $point['x'];
$y = $point['y'];
$z = $point['z'];
Expand Down Expand Up @@ -446,16 +451,16 @@ public static function parseColumns($options)
file_put_contents($tmp_dir . '/' . $tmp_file . ".shx", file_get_contents(substr($options['uri'], 0, strlen($options['uri']) - 4) . ".shx"));

// Along this file the class will use file.shx and file.dbf
$shp = new ShapeReader($tmp_dir . '/' . $tmp_file . ".shp", array('noparts' => false));
$shape_file = new Shapefile($tmp_dir . '/' . $tmp_file . ".shp", array('noparts' => false));
} else {
// along this file the class will use file.shx and file.dbf
$shp = new ShapeReader($options['uri'], array('noparts' => false));
$shape_file = new Shapefile($options['uri'], array('noparts' => false));
}
} catch (Exception $e) {
\App::abort(400, "The shape contents couldn't be retrieved, make sure the shape file is valid, zipped shape files are not yet supported.");
}

$record = $shp->getNext();
$record = $shape_file->getRecord();

// Read meta data
if (!$record) {
Expand All @@ -464,7 +469,7 @@ public static function parseColumns($options)
}

// Get the dBASE fields
$dbf_fields = $record->getDbfData();
$dbf_fields = $record['dbf'];

$column_index = 0;

Expand All @@ -476,7 +481,7 @@ public static function parseColumns($options)
$column_index++;
}

$shape_type = self::$RECORD_TYPES[$record->getTypeCode()];
$shape_type = self::$RECORD_TYPES[$shape_file->getShapeType()];

// Get the geographical column names
switch (strtolower($shape_type)) {
Expand Down Expand Up @@ -536,30 +541,27 @@ public static function parseGeoProperty($options, $columns)
file_put_contents($tmp_dir . '/' . $tmp_file . ".dbf", file_get_contents(substr($options['uri'], 0, strlen($options['uri']) - 4) . ".dbf"));
file_put_contents($tmp_dir . '/' . $tmp_file . ".shx", file_get_contents(substr($options['uri'], 0, strlen($options['uri']) - 4) . ".shx"));

$shp = new ShapeReader($tmp_dir . '/' . $tmp_file . ".shp", array('noparts' => false));
$shape_file = new ShapeFile($tmp_dir . '/' . $tmp_file . ".shp", array('noparts' => false));
} else {
$shp = new ShapeReader($options['uri'], array('noparts' => false));
$shape_file = new ShapeFile($options['uri'], array('noparts' => false));
}

$record = $shp->getNext();
$record = $shape_file->getRecord();

// read meta data
if (!$record) {
$uri = $options['uri'];
\App::abort(400, "We failed to retrieve a record from the provided shape file on uri $uri, make sure the corresponding dbf and shx files are at the same location.");
}

$shp_data = $record->getShpData();

$geo_properties = array();


// Get the geographical column names
// Either multiple coordinates will be set (identified by the parts)
// or a lat long pair will be set (identified by x and y)
$shp_data = $record->getShpData();
$shp_data = $record['shp'];

$geo_properties = array();

$shape_type = self::$RECORD_TYPES[$record->getTypeCode()];
$shape_type = self::$RECORD_TYPES[$shape_file->getShapeType()];

switch (strtolower($shape_type)) {
case 'point':
Expand Down
Loading

0 comments on commit d800368

Please sign in to comment.