From 87a8770bb45deec37c928270d32b6db0e2226da7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Sun, 3 Mar 2019 20:13:16 -0500 Subject: [PATCH 1/7] Create entity file for supported areas --- src/Entity/SupportedArea.php | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/Entity/SupportedArea.php diff --git a/src/Entity/SupportedArea.php b/src/Entity/SupportedArea.php new file mode 100644 index 00000000..c8914998 --- /dev/null +++ b/src/Entity/SupportedArea.php @@ -0,0 +1,85 @@ +date_create = new DateTime(); + } + + public function getID() + { + return $this->id; + } + + public function setDateCreate(DateTime $date_create) + { + $this->date_create = $date_create; + return $this; + } + + public function getDateCreate() + { + returh $this->date_Create; + } + + public function setName($name) + { + $this->name = $name; + return $this; + } + + public function getName() + { + return $this->name; + } + + public function setSupportedArea(Polygon $polygon) + { + $this->supported_area = $polygon; + + return $this; + } + + public function getSupportedArea() + { + return $this->supported_area; + } +} From 84eb00f9e5164d26f0839ca973905bb09f378f1e Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 5 Mar 2019 03:28:51 -0500 Subject: [PATCH 2/7] Create function to retrieve the enclosed area from a KML file --- src/Service/KMLFileImporter.php | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/Service/KMLFileImporter.php diff --git a/src/Service/KMLFileImporter.php b/src/Service/KMLFileImporter.php new file mode 100644 index 00000000..627e63d7 --- /dev/null +++ b/src/Service/KMLFileImporter.php @@ -0,0 +1,70 @@ +supported_area = new SupportedArea(); + } + + public function getMapData(UploadedFile $file) + { + $coordinate_array = array(); + $point_array = array(); + $reader = new XMLReader(); + $reader->open($file); + + while($reader->read()) + { + if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "Placemark") + { + while($reader->read()) + { + if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "name") + { + $placemark_name = $reader->readInnerXML(); + echo $placemark_name."\n"; + $supported_area->setName($placemark_name); + + } + if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "coordinates") + { + $coordinates = $reader->readInnerXML(); + // clean and parse the coordinates data from KML + $coordinates = preg_replace('/\s\s+/', ',', $coordinates); + $parsed_coordinates = explode(',', $coordinates); + + for ($x = 0; $x < sizeof($parsed_coordinates); $x++) + { + if (($x%3 != 0) && ($parsed_coordinates[$x] != "")) + { + $coordinate_array[] = $parsed_coordinates[$x]; + } + } + // create an array of Points for the Polygon constructor + $i = 0; + while($i < sizeof($coordinate_array)) + { + $point_array[] = new Point($coordinate_array[$i], $coordinate_array[$++i]); + $i++; + } + $area = new Polygon(array(new LineString($point_array))); + $supported_area->setSupportedArea($area); + } + } + break; + } + } + $reader->close(); + } +} From 5def677267779450f189ce29d03b737f27a2a069 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 6 Mar 2019 19:52:05 -0500 Subject: [PATCH 3/7] Create command that takes a kml file as an argument. Fix errors with the SupportedArea entity file and the KMLImporter service. --- src/Command/ImportKMLFileCommand.php | 45 ++++++++++++++++++++++++++++ src/Entity/SupportedArea.php | 15 +++++----- src/Service/KMLFileImporter.php | 26 +++++++++++----- 3 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 src/Command/ImportKMLFileCommand.php diff --git a/src/Command/ImportKMLFileCommand.php b/src/Command/ImportKMLFileCommand.php new file mode 100644 index 00000000..9695059b --- /dev/null +++ b/src/Command/ImportKMLFileCommand.php @@ -0,0 +1,45 @@ +setName('supportedarea:add') + ->setDescription('Extracts map data of the supported area from the KML file and saves to database') + ->setHelp('Gets the coordinates of the supported area and saves to the database') + ->addArgument('file', InputArgument::REQUIRED, 'Path to the KML file'); + } + + public function __construct(KMLFileImporter $importer) + { + $this->importer = $importer; + + parent::__construct(); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $kml_file = $input->getArgument('file'); + try + { + $fh = fopen($kml_file, "r"); + } + catch (Exception $e) + { + throw new Exception('The file "' . $kml_file . '" could not be read.'); + } + + $this->importer->getMapData($kml_file); + } +} diff --git a/src/Entity/SupportedArea.php b/src/Entity/SupportedArea.php index c8914998..0f70c39e 100644 --- a/src/Entity/SupportedArea.php +++ b/src/Entity/SupportedArea.php @@ -29,7 +29,7 @@ class SupportedArea // name of the supported area /** - * @ORM\Colume(type="string", length=25) + * @ORM\Column(type="string", length=80) */ protected $name; @@ -37,7 +37,7 @@ class SupportedArea /** * @ORM\Column(type="polygon") */ - protected $supported_area; + protected $coverage_area; public function __construct() { @@ -57,7 +57,7 @@ class SupportedArea public function getDateCreate() { - returh $this->date_Create; + return $this->date_Create; } public function setName($name) @@ -71,15 +71,16 @@ class SupportedArea return $this->name; } - public function setSupportedArea(Polygon $polygon) + public function setCoverageArea(Polygon $polygon) { - $this->supported_area = $polygon; + $this->coverage_area = $polygon; return $this; } - public function getSupportedArea() + public function getCoverageArea() { - return $this->supported_area; + return $this->coverage_area; } } + diff --git a/src/Service/KMLFileImporter.php b/src/Service/KMLFileImporter.php index 627e63d7..9e996230 100644 --- a/src/Service/KMLFileImporter.php +++ b/src/Service/KMLFileImporter.php @@ -2,9 +2,11 @@ namespace App\Service; +use XMLReader; + use App\Entity\SupportedArea; -use Symfony\Component\HttpFoundation\File\UploadedFile; +use Doctrine\Common\Persistence\ObjectManager; use CrEOF\Spatial\PHP\Types\Geometry\Polygon; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -12,17 +14,21 @@ use CrEOF\Spatial\PHP\Types\Geometry\LineString; class KMLFileImporter { - public function __construct() + protected $em; + + public function __construct(ObjectManager $em) { - $this->supported_area = new SupportedArea(); + $this->em = $em; } - public function getMapData(UploadedFile $file) + public function getMapData($fh) { $coordinate_array = array(); $point_array = array(); + $supported_area = new SupportedArea(); + $reader = new XMLReader(); - $reader->open($file); + $reader->open($fh); while($reader->read()) { @@ -33,7 +39,6 @@ class KMLFileImporter if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "name") { $placemark_name = $reader->readInnerXML(); - echo $placemark_name."\n"; $supported_area->setName($placemark_name); } @@ -55,16 +60,21 @@ class KMLFileImporter $i = 0; while($i < sizeof($coordinate_array)) { - $point_array[] = new Point($coordinate_array[$i], $coordinate_array[$++i]); + $point_array[] = new Point($coordinate_array[$i], $coordinate_array[++$i]); $i++; } $area = new Polygon(array(new LineString($point_array))); - $supported_area->setSupportedArea($area); + $supported_area->setCoverageArea($area); } } break; } } $reader->close(); + + // add supported area + $em = $this->em; + $em->persist($supported_area); + $em->flush(); } } From f93b675976f0d85483f3e9b89a9cd71f3a1721e7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 7 Mar 2019 02:37:14 -0500 Subject: [PATCH 4/7] Use EntityManagerInterface instead of ObjectManager for ORM --- src/Service/KMLFileImporter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/KMLFileImporter.php b/src/Service/KMLFileImporter.php index 9e996230..ac040c35 100644 --- a/src/Service/KMLFileImporter.php +++ b/src/Service/KMLFileImporter.php @@ -6,7 +6,7 @@ use XMLReader; use App\Entity\SupportedArea; -use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\ORM\EntityManagerInterface; use CrEOF\Spatial\PHP\Types\Geometry\Polygon; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -16,7 +16,7 @@ class KMLFileImporter { protected $em; - public function __construct(ObjectManager $em) + public function __construct(EntityManagerInterface $em) { $this->em = $em; } From d24be90314dae75eec943a4f84c2c4977e75e90f Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Sun, 10 Mar 2019 19:47:33 +0800 Subject: [PATCH 5/7] Refactor import kml to handle multiple polygons #141 --- src/Command/ImportKMLFileCommand.php | 10 +---- src/Service/KMLFileImporter.php | 56 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/Command/ImportKMLFileCommand.php b/src/Command/ImportKMLFileCommand.php index 9695059b..4f378498 100644 --- a/src/Command/ImportKMLFileCommand.php +++ b/src/Command/ImportKMLFileCommand.php @@ -15,7 +15,7 @@ class ImportKMLFileCommand extends Command { protected function configure() { - $this->setName('supportedarea:add') + $this->setName('supportedarea:import') ->setDescription('Extracts map data of the supported area from the KML file and saves to database') ->setHelp('Gets the coordinates of the supported area and saves to the database') ->addArgument('file', InputArgument::REQUIRED, 'Path to the KML file'); @@ -31,14 +31,6 @@ class ImportKMLFileCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { $kml_file = $input->getArgument('file'); - try - { - $fh = fopen($kml_file, "r"); - } - catch (Exception $e) - { - throw new Exception('The file "' . $kml_file . '" could not be read.'); - } $this->importer->getMapData($kml_file); } diff --git a/src/Service/KMLFileImporter.php b/src/Service/KMLFileImporter.php index ac040c35..60bcfa54 100644 --- a/src/Service/KMLFileImporter.php +++ b/src/Service/KMLFileImporter.php @@ -23,9 +23,7 @@ class KMLFileImporter public function getMapData($fh) { - $coordinate_array = array(); - $point_array = array(); - $supported_area = new SupportedArea(); + $placemark_name = ''; $reader = new XMLReader(); $reader->open($fh); @@ -39,42 +37,46 @@ class KMLFileImporter if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "name") { $placemark_name = $reader->readInnerXML(); - $supported_area->setName($placemark_name); - } + if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "coordinates") { - $coordinates = $reader->readInnerXML(); - // clean and parse the coordinates data from KML - $coordinates = preg_replace('/\s\s+/', ',', $coordinates); - $parsed_coordinates = explode(',', $coordinates); + // each polygon is a new area + $supported_area = new SupportedArea(); + $supported_area->setName($placemark_name); - for ($x = 0; $x < sizeof($parsed_coordinates); $x++) + $point_array = []; + $coordinates = $reader->readInnerXML(); + + // get each line + $coord_split = explode("\n", $coordinates); + + // go through all the coordinates + foreach ($coord_split as $coord) { - if (($x%3 != 0) && ($parsed_coordinates[$x] != "")) - { - $coordinate_array[] = $parsed_coordinates[$x]; - } + // skip blank lines + $coord_trim = trim($coord); + if (strlen($coord_trim) <= 0) + continue; + + // echo "$coord_trim\n"; + + $point_split = explode(',', $coord_trim); + + $point_array[] = new Point($point_split[0], $point_split[1]); } - // create an array of Points for the Polygon constructor - $i = 0; - while($i < sizeof($coordinate_array)) - { - $point_array[] = new Point($coordinate_array[$i], $coordinate_array[++$i]); - $i++; - } - $area = new Polygon(array(new LineString($point_array))); + + $area = new Polygon([new LineString($point_array)]); $supported_area->setCoverageArea($area); + + // add supported area + $this->em->persist($supported_area); } } - break; } } $reader->close(); - // add supported area - $em = $this->em; - $em->persist($supported_area); - $em->flush(); + $this->em->flush(); } } From 2ffc856b10f50f6b9665a4a788388001ae74b295 Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Sun, 10 Mar 2019 22:33:35 +0800 Subject: [PATCH 6/7] Add GeofenceTracker service and test command #141 --- src/Command/ImportKMLFileCommand.php | 2 ++ src/Command/TestGeofenceCommand.php | 44 ++++++++++++++++++++++++++++ src/Service/GeofenceTracker.php | 35 ++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 src/Command/TestGeofenceCommand.php create mode 100644 src/Service/GeofenceTracker.php diff --git a/src/Command/ImportKMLFileCommand.php b/src/Command/ImportKMLFileCommand.php index 4f378498..4d2e71a2 100644 --- a/src/Command/ImportKMLFileCommand.php +++ b/src/Command/ImportKMLFileCommand.php @@ -13,6 +13,8 @@ use App\Service\KMLFileImporter; class ImportKMLFileCommand extends Command { + protected $importer; + protected function configure() { $this->setName('supportedarea:import') diff --git a/src/Command/TestGeofenceCommand.php b/src/Command/TestGeofenceCommand.php new file mode 100644 index 00000000..1397f08f --- /dev/null +++ b/src/Command/TestGeofenceCommand.php @@ -0,0 +1,44 @@ +setName('test:geofence') + ->setDescription('Test geofence tracker service.') + ->setHelp('Test the geofence tracker service.') + ->addArgument('long', InputArgument::REQUIRED, 'Longitude') + ->addArgument('lat', InputArgument::REQUIRED, 'Latitude'); + } + + public function __construct(GeofenceTracker $geo) + { + $this->geo = $geo; + + parent::__construct(); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $long = $input->getArgument('long'); + $lat = $input->getArgument('lat'); + + if ($this->geo->isCovered($long, $lat)) + echo "In geofence\n"; + else + echo "NOT in geofence\n"; + } +} diff --git a/src/Service/GeofenceTracker.php b/src/Service/GeofenceTracker.php new file mode 100644 index 00000000..b2052e02 --- /dev/null +++ b/src/Service/GeofenceTracker.php @@ -0,0 +1,35 @@ +em = $em; + } + + public function isCovered($long, $lat) + { + // see if the point is in any of the polygons + $query = $this->em->createQuery('SELECT count(s) from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true') + ->setParameter('long', $long) + ->setParameter('lat', $lat); + + // number of polygons that contain the point + $count = $query->getSingleScalarResult(); + + if ($count > 0) + return true; + + return false; + } +} From 27372264e9a638e01f26a56d3229fb2b4e4b3b9b Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Mon, 11 Mar 2019 01:32:52 +0800 Subject: [PATCH 7/7] Add geofence check for job order request api call #141 --- src/Controller/APIController.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index d5fa3b3a..a9a23caf 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -25,6 +25,7 @@ use App\Ramcar\JOEventType; use App\Service\InvoiceCreator; use App\Service\RisingTideGateway; use App\Service\MQTTClient; +use App\Service\GeofenceTracker; use App\Entity\MobileSession; use App\Entity\Customer; @@ -766,7 +767,7 @@ class APIController extends Controller return $res->getReturnResponse(); } - public function requestJobOrder(Request $req, InvoiceCreator $ic) + public function requestJobOrder(Request $req, InvoiceCreator $ic, GeofenceTracker $geo) { // check required parameters and api key $required_params = [ @@ -793,6 +794,19 @@ class APIController extends Controller // instructions $instructions = $req->request->get('delivery_instructions', ''); + // longitude and latitude + $long = $req->request->get('long'); + $lat = $req->request->get('lat'); + + // geofence + $is_covered = $geo->isCovered($long, $lat); + if (!$is_covered) + { + $res->setError(true) + ->setErrorMessage('Location is not covered by our service.'); + return $res->getReturnResponse(); + } + $jo = new JobOrder(); $jo->setSource(TransactionOrigin::MOBILE_APP) @@ -836,9 +850,7 @@ class APIController extends Controller } $jo->setWarrantyClass($warr); - // longitude and latitude - $long = $req->request->get('long'); - $lat = $req->request->get('lat'); + // set coordinates $point = new Point($long, $lat); $jo->setCoordinates($point);