#32 add point type + Address: add Point field + add null on nullable fields

This commit is contained in:
nobohan 2021-04-19 12:12:55 +02:00
parent ebd58d4229
commit 7d1a1c4004
5 changed files with 214 additions and 8 deletions

View File

@ -188,7 +188,8 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
$container->prependExtensionConfig('doctrine', array( $container->prependExtensionConfig('doctrine', array(
'dbal' => [ 'dbal' => [
'types' => [ 'types' => [
'dateinterval' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class 'dateinterval' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class,
'json' => \Chill\MainBundle\Doctrine\Type\PointType::class
] ]
] ]
)); ));

View File

@ -0,0 +1,72 @@
<?php
namespace Chill\MainBundle\Doctrine\Type;
use Chill\MainBundle\Entity\Point;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Chill\MainBundle\Entity\PointException;
/**
* A Type for Doctrine to implement the Geography Point type
* implemented by Postgis on postgis+postgresql databases
*
*/
class PointType extends Type {
const POINT = 'point';
/**
*
* @param array $fieldDeclaration
* @param AbstractPlatform $platform
* @return type
*/
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return 'geometry(POINT,'.Point::$SRID.')';
}
/**
*
* @param type $value
* @param AbstractPlatform $platform
* @return Point
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return Point::fromGeoJson($value);
}
public function getName()
{
return self::POINT;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value->toWKT();
}
public function canRequireSQLConversion()
{
return true;
}
public function convertToPHPValueSQL($sqlExpr, $platform)
{
return 'ST_AsGeoJSON('.$sqlExpr.') ';
}
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
{
return $sqlExpr;
}
}

View File

@ -45,49 +45,49 @@ class Address
private $postcode; private $postcode;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=16, nullable=true) * @ORM\Column(type="string", length=16, nullable=true)
*/ */
private $floor; private $floor;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=16, nullable=true) * @ORM\Column(type="string", length=16, nullable=true)
*/ */
private $corridor; private $corridor;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=16, nullable=true) * @ORM\Column(type="string", length=16, nullable=true)
*/ */
private $steps; private $steps;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
*/ */
private $buildingName; private $buildingName;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=16, nullable=true) * @ORM\Column(type="string", length=16, nullable=true)
*/ */
private $flat; private $flat;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
*/ */
private $distribution; private $distribution;
/** /**
* @var string * @var string|null
* *
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
*/ */
@ -120,6 +120,15 @@ class Address
*/ */
private $isNoAddress = false; private $isNoAddress = false;
/**
* A geospatial field storing the coordinates of the Address
*
* @var Point|null
*
* @ORM\Column(type="Point", nullable=true)
*/
private $point;
/** /**
* A list of metadata, added by customizable fields * A list of metadata, added by customizable fields
* *

View File

@ -0,0 +1,96 @@
<?php
namespace Chill\MainBundle\Entity;
use \JsonSerializable;
/**
* Description of Point
*
*/
class Point implements JsonSerializable {
private $lat;
private $lon;
public static $SRID = '4326';
private function __construct($lon, $lat) {
$this->lat = $lat;
$this->lon = $lon;
}
public function toGeoJson() {
$array = $this->toArrayGeoJson();
return \json_encode($array);
}
public function jsonSerialize() {
return $this->toArrayGeoJson();
}
public function toArrayGeoJson() {
return array("type" => "Point",
"coordinates" => array ($this->lon, $this->lat));
}
/**
*
* @return string
*/
public function toWKT() {
return 'SRID='.self::$SRID.';POINT('.$this->lon.' '.$this->lat.')';
}
/**
*
* @param type $geojson
* @return Point
*/
public static function fromGeoJson($geojson)
{
$a = json_decode($geojson);
//check if the geojson string is correct
if ($a == null or !isset($a->type) or !isset($a->coordinates)){
throw PointException::badJsonString($geojson);
}
if ($a->type != "Point"){
throw PointException::badGeoType();
} else {
$lat = $a->coordinates[1];
$lon = $a->coordinates[0];
return Point::fromLonLat($lon, $lat);
}
}
public static function fromLonLat($lon, $lat)
{
if (($lon > -180 && $lon < 180) && ($lat > -90 && $lat < 90))
{
return new Point($lon, $lat);
} else {
throw PointException::badCoordinates($lon, $lat);
}
}
public static function fromArrayGeoJson($array)
{
if ($array['type'] == 'Point' &&
isset($array['coordinates']))
{
return self::fromLonLat($array['coordinates'][0], $array['coordinates'][1]);
}
}
public function getLat()
{
return $this->lat;
}
public function getLon()
{
return $this->lon;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Chill\MainBundle\Entity;
use \Exception;
/**
* Description of PointException
*
*/
class PointException extends Exception {
public static function badCoordinates($lon, $lat)
{
return new self("les coordonnées fournies sont invalides dans le système de projection utilisé (longitude = $lon , latitude = $lat)");
}
public static function badJsonString($str)
{
return new self("la chaine JSON n'est pas valide : $str");
}
public static function badGeoType()
{
return new self("le type de l'objet GeoJSON est invalide");
}
}