diff --git a/module/config/event_subscribers.php b/module/config/event_subscribers.php index 59eac96..e432193 100644 --- a/module/config/event_subscribers.php +++ b/module/config/event_subscribers.php @@ -11,4 +11,5 @@ return array( 'Netzmacht\Contao\Leaflet\Subscriber\BootSubscriber', 'Netzmacht\Contao\Leaflet\Subscriber\HashSubscriber', + 'Netzmacht\Contao\Leaflet\Subscriber\GeoJsonSubscriber', ); diff --git a/src/Netzmacht/Contao/Leaflet/Event/ConvertToGeoJsonEvent.php b/src/Netzmacht/Contao/Leaflet/Event/ConvertToGeoJsonEvent.php new file mode 100644 index 0000000..f1d7e50 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/ConvertToGeoJsonEvent.php @@ -0,0 +1,91 @@ + + * @copyright 2015 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Netzmacht\LeafletPHP\Definition; +use Netzmacht\LeafletPHP\Definition\GeoJson\GeoJsonObject; +use Symfony\Component\EventDispatcher\Event; + +/** + * Class ConvertToGeoJsonEvent is emitted when the DefinitionMapper converts a definition to a geo json feature. + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class ConvertToGeoJsonEvent extends Event +{ + const NAME = 'leaflet.mapper.convert-to-geojson'; + + /** + * The definition. + * + * @var Definition + */ + private $definition; + + /** + * The GeoJSON object. + * + * @var GeoJsonObject + */ + private $geoJson; + + /** + * The definition model. + * + * @var mixed + */ + private $model; + + /** + * Construct. + * + * @param Definition $definition The definition. + * @param GeoJsonObject $geoJson The GeoJSON object. + * @param mixed $model The corresponding model. Usually a \Model but could be everything. + */ + public function __construct(Definition $definition, GeoJsonObject $geoJson, $model) + { + $this->definition = $definition; + $this->geoJson = $geoJson; + $this->model = $model; + } + + /** + * Get the definition. + * + * @return Definition + */ + public function getDefinition() + { + return $this->definition; + } + + /** + * Get the geoJson representation. + * + * @return GeoJsonObject + */ + public function getGeoJson() + { + return $this->geoJson; + } + + /** + * Get the model. + * + * @return mixed + */ + public function getModel() + { + return $this->model; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php index 08785dc..d448b66 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php @@ -12,10 +12,13 @@ namespace Netzmacht\Contao\Leaflet\Mapper; use Netzmacht\Contao\Leaflet\Event\BuildDefinitionEvent; +use Netzmacht\Contao\Leaflet\Event\ConvertToGeoJsonEvent; use Netzmacht\Contao\Leaflet\Event\GetHashEvent; use Netzmacht\LeafletPHP\Definition; +use Netzmacht\LeafletPHP\Definition\GeoJson\ConvertsToGeoJsonFeature; use Netzmacht\LeafletPHP\Definition\GeoJson\Feature; use Netzmacht\LeafletPHP\Definition\GeoJson\FeatureCollection; +use Netzmacht\LeafletPHP\Definition\GeoJson\GeoJsonFeature; use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds; use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher; @@ -132,6 +135,30 @@ class DefinitionMapper ); } + /** + * Convert a definition to a geo json feature. + * + * @param Definition $definition The leaflet definition object. + * @param mixed $model The corresponding definition model. + * + * @return GeoJsonFeature + */ + public function convertToGeoJsonFeature(Definition $definition, $model) + { + if ($definition instanceof GeoJsonFeature) { + $feature = $definition; + } elseif ($definition instanceof ConvertsToGeoJsonFeature) { + $feature = $definition->toGeoJsonFeature(); + } else { + throw new \RuntimeException('Unsupported definition'); + } + + $event = new ConvertToGeoJsonEvent($definition, $feature, $model); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $feature; + } + /** * Get the hash of a model. * diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php index 4e5c034..796e797 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php @@ -17,7 +17,6 @@ use Netzmacht\Contao\Leaflet\Model\MarkerModel; use Netzmacht\Contao\Leaflet\Frontend\RequestUrl; use Netzmacht\JavascriptBuilder\Type\Expression; use Netzmacht\LeafletPHP\Definition; -use Netzmacht\LeafletPHP\Definition\GeoJson\Feature; use Netzmacht\LeafletPHP\Definition\GeoJson\FeatureCollection; use Netzmacht\LeafletPHP\Definition\Group\GeoJson; use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds; @@ -59,7 +58,6 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper $elementId = null ) { if ($model->deferred) { - if ($model->pointToLayer || $model->affectBounds) { $layer = new GeoJson($this->getElementId($model, $elementId)); @@ -100,15 +98,10 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper if ($collection) { foreach ($collection as $item) { $marker = $mapper->handle($item); + $point = $mapper->convertToGeoJsonFeature($marker, $item); - if ($marker instanceof Marker) { - $feature = $marker->toGeoJsonFeature(); - - if ($item->ignoreForBounds || !$model->affectBounds) { - $feature->setProperty('ignoreForBounds', true); - } - - $definition->addData($feature, true); + if ($point) { + $definition->addData($point); } } } @@ -130,14 +123,9 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper if ($collection) { foreach ($collection as $item) { $marker = $mapper->handle($item); + $point = $mapper->convertToGeoJsonFeature($marker, $item); - if ($marker instanceof Marker) { - $point = $marker->toGeoJsonFeature(); - - if ($point instanceof Feature && ($item->ignoreForBounds || !$model->affectBounds)) { - $point->setProperty('ignoreForBounds', true); - } - + if ($point) { $feature->addFeature($point); } } diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php index d42dd11..964db57 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php @@ -22,8 +22,6 @@ use Netzmacht\LeafletPHP\Definition\GeoJson\Feature; use Netzmacht\LeafletPHP\Definition\GeoJson\FeatureCollection; use Netzmacht\LeafletPHP\Definition\GeoJson\GeoJsonFeature; use Netzmacht\LeafletPHP\Definition\Group\GeoJson; -use Netzmacht\LeafletPHP\Definition\Group\LayerGroup; -use Netzmacht\LeafletPHP\Definition\Layer; use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds; use Netzmacht\LeafletPHP\Definition\Vector; @@ -109,15 +107,10 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper if ($collection) { foreach ($collection as $item) { - $vector = $mapper->handle($item); - - if ($vector instanceof ConvertsToGeoJsonFeature) { - $feature = $vector->toGeoJsonFeature(); - - if ($feature instanceof Feature && ($item->ignoreForBounds || !$model->affectBounds)) { - $feature->setProperty('ignoreForBounds', true); - } + $vector = $mapper->handle($item); + $feature = $mapper->convertToGeoJsonFeature($vector, $item); + if ($feature) { $definition->addData($feature, true); } } @@ -132,28 +125,21 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper */ public function handleGeoJson(\Model $model, DefinitionMapper $mapper, LatLngBounds $bounds = null) { - $feature = new FeatureCollection(); + $definition = new FeatureCollection(); $collection = $this->loadVectorModels($model); if ($collection) { foreach ($collection as $item) { - $vector = $mapper->handle($item); + $vector = $mapper->handle($item); + $feature = $mapper->convertToGeoJsonFeature($vector, $item); - if ($vector instanceof ConvertsToGeoJsonFeature) { - $vector = $vector->toGeoJsonFeature(); - } - - if ($vector instanceof GeoJsonFeature) { - if ($vector instanceof Feature && ($item->ignoreForBounds || !$model->affectBounds)) { - $vector->setProperty('ignoreForBounds', true); - } - - $feature->addFeature($vector); + if ($feature) { + $definition->addFeature($feature, true); } } } - return $feature; + return $definition; } /** diff --git a/src/Netzmacht/Contao/Leaflet/Subscriber/GeoJsonSubscriber.php b/src/Netzmacht/Contao/Leaflet/Subscriber/GeoJsonSubscriber.php new file mode 100644 index 0000000..ce5ab0a --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Subscriber/GeoJsonSubscriber.php @@ -0,0 +1,133 @@ + + * @copyright 2015 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Subscriber; + +use Netzmacht\Contao\Leaflet\Dca\Vector; +use Netzmacht\Contao\Leaflet\Event\ConvertToGeoJsonEvent; +use Netzmacht\Contao\Leaflet\Model\LayerModel; +use Netzmacht\Contao\Leaflet\Model\MarkerModel; +use Netzmacht\Contao\Leaflet\Model\VectorModel; +use Netzmacht\LeafletPHP\Definition\GeoJson\Feature; +use Netzmacht\LeafletPHP\Definition\HasPopup; +use Netzmacht\LeafletPHP\Definition\UI\Marker; +use Netzmacht\LeafletPHP\Definition\Vector\Circle; +use Netzmacht\LeafletPHP\Definition\Vector\CircleMarker; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class GeoJsonSubscriber implements EventSubscriberInterface +{ + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array( + ConvertToGeoJsonEvent::NAME => array( + array('addPopup'), + array('enrichMarker'), + array('enrichVector'), + array('enrichCircle') + ) + ); + } + + /** + * Add popup property for definitions with an popup. + * + * @param ConvertToGeoJsonEvent $event The subscribed event. + * + * @return void + */ + public function addPopup(ConvertToGeoJsonEvent $event) + { + $feature = $event->getGeoJson(); + $definition = $event->getDefinition(); + + if ($definition instanceof HasPopup && $feature instanceof Feature) { + if ($definition->getPopup()) { + $feature->setProperty('popup', $definition->getPopup()); + } + + if ($definition->getPopupContent()) { + $feature->setProperty('popupContent', $definition->getPopupContent()); + } + } + } + + /** + * @param ConvertToGeoJsonEvent $event + */ + public function enrichMarker(ConvertToGeoJsonEvent $event) + { + $feature = $event->getGeoJson(); + $definition = $event->getDefinition(); + $model = $event->getModel(); + + if ($definition instanceof Marker && $model instanceof MarkerModel && $feature instanceof Feature) { + if ($model->featureData) { + $feature->setProperty('data', json_decode($model->featureData, true)); + } + + if ($model->ignoreForBounds) { + $feature->setProperty('ignoreForBounds', true); + } else { + $parent = LayerModel::findByPk($model->pid); + + if ($parent && !$parent->affectBounds) { + $feature->setProperty('ignoreForBounds', true); + } + } + } + } + + /** + * @param ConvertToGeoJsonEvent $event + */ + public function enrichVector(ConvertToGeoJsonEvent $event) + { + $feature = $event->getGeoJson(); + $definition = $event->getDefinition(); + $model = $event->getModel(); + + if ($definition instanceof Vector && $model instanceof VectorModel && $feature instanceof Feature) { + if ($model->featureData) { + $feature->setProperty('data', json_decode($model->featureData, true)); + } + + if ($model->ignoreForBounds) { + $feature->setProperty('ignoreForBounds', true); + } else { + $parent = LayerModel::findByPk($model->pid); + + if ($parent && !$parent->affectBounds) { + $feature->setProperty('ignoreForBounds', true); + } + } + } + } + + /** + * Enrich the the circle with constructor arguments. + * + * @param ConvertToGeoJsonEvent $event The subscribed events. + * @return void + */ + public function enrichCircle(ConvertToGeoJsonEvent $event) + { + $feature = $event->getGeoJson(); + $definition = $event->getDefinition(); + + if ($definition instanceof Circle && !$definition instanceof CircleMarker && $feature instanceof Feature) { + $feature->setProperty('arguments', array($definition->getLatLng(), $definition->getRadius())); + } + } +}