Skip to content

Commit

Permalink
Merge pull request #985 from City-of-Helsinki/UHF-11027
Browse files Browse the repository at this point in the history
UHF-11027: Fix ploughing schedule component
  • Loading branch information
hyrsky authored Dec 2, 2024
2 parents cdaae44 + 57b89c9 commit c5725e3
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 130 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
"@lint-php",
"@test-php"
],
"test-php": "vendor/bin/phpunit -c phpunit.xml.dist",
"test-php": "vendor/bin/phpunit -c $PWD/phpunit.xml.dist",
"lint-php": "vendor/bin/phpcs --standard=Drupal",
"copy-commit-message-script": "make copy-commit-message-script",
"post-install-cmd": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
services:
_defaults:
autowire: true
autoconfigure: true

logger.channel.helfi_kymp_content:
parent: logger.channel_base
arguments:
Expand All @@ -9,3 +13,5 @@ services:
arguments: ['@logger.channel.helfi_kymp_content']
tags:
- { name: event_subscriber }

Drupal\helfi_kymp_content\StreetDataService: ~
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@

namespace Drupal\helfi_kymp_content\Plugin\DataType;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\Attribute\DataType;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\Plugin\DataType\Map;
use Drupal\helfi_kymp_content\TypedData\StreetDataDefinition;

/**
* Street data type.
*
* @DataType(
* id = "street_data",
* label = @Translation("Street data"),
* constraints = {},
* definition_class = "\Drupal\helfi_kymp_content\TypedData\StreetDataDefinition"
* )
*/
#[DataType(
id: "street_data",
label: new TranslatableMarkup("Street data"),
definition_class: StreetDataDefinition::class,
constraints: [],
)]
class StreetData extends Map {

/**
Expand All @@ -25,7 +27,7 @@ class StreetData extends Map {
public static function propertyDefinitions(): array {
$properties = [];

$properties['id'] = DataDefinition::create('integer')
$properties['id'] = DataDefinition::create('string')
->setLabel('id')
->setRequired(TRUE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@

use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\TypedDataTrait;
use Drupal\helfi_kymp_content\Plugin\DataType\StreetData;
use Drupal\helfi_kymp_content\StreetDataService;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Datasource\DatasourcePluginBase;
use GuzzleHttp\ClientInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
Expand All @@ -25,31 +23,17 @@
*/
class HelfiStreetDataSource extends DatasourcePluginBase implements DatasourceInterface {

use TypedDataTrait;

public const API_URL = 'https://kartta.hel.fi/ws/geoserver/avoindata/wfs';

/**
* The client.
*
* @var \GuzzleHttp\ClientInterface
*/
protected ClientInterface $client;

/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected LoggerInterface $logger;
protected StreetDataService $client;

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->client = $container->get('http_client');
$instance->logger = $container->get('logger.channel.helfi_kymp_content');
$instance->client = $container->get(StreetDataService::class);
return $instance;
}

Expand All @@ -72,76 +56,13 @@ public function load($id) {
* {@inheritdoc}
*/
public function loadMultiple(array $ids): array {
$query = http_build_query([
'request' => 'GetFeature',
'service' => 'WFS',
'version' => '1.1.0',
'typeName' => 'avoindata:YLRE_Katualue_alue',
'propertyname' => 'avoindata:kadun_nimi,avoindata:kayttotarkoitus,avoindata:yllapitoluokka,avoindata:pituus',
]);
$uri = sprintf('%s?%s', 'https://kartta.hel.fi/ws/geoserver/avoindata/wfs', $query);
$streetData = $this->client->getStreetData();

try {
$content = $this->client->request('GET', $uri);
$xmlResult = $content->getBody()->getContents();
if (!$xmlResult) {
return [];
}
if ($ids) {
return array_intersect_key($streetData, array_flip($ids));
}
catch (\Exception $e) {
$this->logger->error("Errors while fetching street data from kartta.hel.fi: {$e->getMessage()}");
return [];
}

libxml_use_internal_errors(TRUE);
$doc = new \DOMDocument(encoding: 'UTF-8');
$doc->loadXML($xmlResult);
$errors = libxml_get_errors();

if ($errors) {
$this->logger->error('Errors while parsing street data xml string.');
return [];
}

$data = [];
foreach ($doc->firstChild->firstChild->childNodes->getIterator() as $street_data) {
$id = NULL;
$single_street = [];

foreach ($street_data->childNodes->getIterator() as $field) {
switch ($field->nodeName) {
case 'avoindata:katualue_id':
$id = $field->nodeValue;
$single_street['id'] = $ids && $id && in_array($id, $ids) ? $id : NULL;
break;

case 'avoindata:kadun_nimi':
$single_street['street_name'] = $field->nodeValue;
break;

case 'avoindata:pituus':
$single_street['length'] = $field->nodeValue;
break;

case 'avoindata:yllapitoluokka':
// Turn field value from III or II to 3 or 2 etc.
$single_street['maintenance_class'] = strlen($field->nodeValue);
break;
}
}

if ($ids && $id && !in_array($id, $ids)) {
continue;
}

$street_data_definition = $this->getTypedDataManager()->createDataDefinition('street_data');
/** @var \Drupal\Core\TypedData\ComplexDataInterface $street_data */
$street_data = $this->getTypedDataManager()->create($street_data_definition);
$street_data->setValue($single_street);
$data[$id] = $street_data;
}

return $data;
return $streetData;
}

/**
Expand All @@ -155,24 +76,7 @@ public function getItemLanguage(ComplexDataInterface $item): string {
* {@inheritdoc}
*/
public function getPropertyDefinitions(): array {
$property_definition = [];

$property_definition['id'] = DataDefinition::create('integer')
->setLabel('id')
->setRequired(TRUE);
$property_definition['street_name'] = DataDefinition::create('string')
->setLabel('Street name')
->addConstraint('Range', ['min' => 0, 'max' => 255])
->setRequired(TRUE);
$property_definition['length'] = DataDefinition::create('integer')
->setLabel('Length')
->setRequired(TRUE);
$property_definition['maintenance_class'] = DataDefinition::create('integer')
->setLabel('Maintenance class')
->addConstraint('Range', ['min' => 0, 'max' => 5])
->setRequired(TRUE);

return $property_definition;
return StreetData::propertyDefinitions();
}

}
113 changes: 113 additions & 0 deletions public/modules/custom/helfi_kymp_content/src/StreetDataService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_kymp_content;

use Drupal\Core\TypedData\TypedDataManagerInterface;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
* Service for fetching street data from kartta.hel.fi.
*/
class StreetDataService {

public const API_URL = 'https://kartta.hel.fi/ws/geoserver/avoindata/wfs';

/**
* Constructs a new StreetDataService instance.
*/
public function __construct(
protected readonly ClientInterface $client,
protected readonly TypedDataManagerInterface $typedDataManager,
#[Autowire(service: 'logger.channel.helfi_kymp_content')]
protected readonly LoggerInterface $logger,
) {
}

/**
* Gets street data.
*
* @return array<int|string, \Drupal\Core\TypedData\ComplexDataInterface>
* Street data.
*/
public function getStreetData(): array {
$query = http_build_query([
'request' => 'GetFeature',
'service' => 'WFS',
'version' => '1.1.0',
'typeName' => 'avoindata:YLRE_Katualue_alue',
'propertyname' => 'avoindata:kadun_nimi,avoindata:yllapitoluokka,avoindata:pituus',
]);
$uri = sprintf('%s?%s', self::API_URL, $query);

try {
$content = $this->client->request('GET', $uri);
$xmlResult = $content->getBody()->getContents();
if (!$xmlResult) {
return [];
}
}
catch (GuzzleException $e) {
$this->logger->error("Errors while fetching street data from kartta.hel.fi: {$e->getMessage()}");
return [];
}

$internal_errors = libxml_use_internal_errors(TRUE);
$doc = new \DOMDocument(encoding: 'UTF-8');
$doc->preserveWhiteSpace = FALSE;
$doc->loadXML($xmlResult);
$errors = libxml_get_errors();
libxml_use_internal_errors($internal_errors);

if ($errors) {
$this->logger->error('Errors while parsing street data xml string.');
return [];
}

$data = [];
foreach ($doc->firstChild->firstChild->childNodes->getIterator() as $street_data) {
if (!$street_data instanceof \DOMElement) {
continue;
}

$id = $street_data->getAttribute('gml:id');
if (!$id) {
continue;
}

$single_street = [
'id' => $id,
];

foreach ($street_data->childNodes->getIterator() as $field) {
switch ($field->nodeName) {
case 'avoindata:kadun_nimi':
$single_street['street_name'] = $field->nodeValue;
break;

case 'avoindata:pituus':
$single_street['length'] = $field->nodeValue;
break;

case 'avoindata:yllapitoluokka':
// Turn field value from III or II to 3 or 2 etc.
$single_street['maintenance_class'] = strlen($field->nodeValue);
break;
}
}

$street_data_definition = $this->typedDataManager->createDataDefinition('street_data');
/** @var \Drupal\Core\TypedData\ComplexDataInterface $street_data */
$street_data = $this->typedDataManager->create($street_data_definition);
$street_data->setValue($single_street);
$data[$id] = $street_data;
}

return $data;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Drupal\helfi_kymp_content\TypedData;

use Drupal\Core\TypedData\ComplexDataDefinitionBase;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\helfi_kymp_content\Plugin\DataType\StreetData;

/**
* The street data definition.
Expand All @@ -15,22 +15,9 @@ class StreetDataDefinition extends ComplexDataDefinitionBase {
/**
* {@inheritDoc}
*/
public function getPropertyDefinitions() {
public function getPropertyDefinitions(): array {
if (!isset($this->propertyDefinitions)) {
$this->propertyDefinitions['id'] = DataDefinition::create('integer')
->setLabel('id')
->setRequired(TRUE);
$this->propertyDefinitions['street_name'] = DataDefinition::create('string')
->setLabel('Street name')
->addConstraint('Range', ['min' => 0, 'max' => 255])
->setRequired(TRUE);
$this->propertyDefinitions['length'] = DataDefinition::create('integer')
->setLabel('Length')
->setRequired(TRUE);
$this->propertyDefinitions['maintenance_class'] = DataDefinition::create('integer')
->setLabel('Maintenance class')
->addConstraint('Range', ['min' => 0, 'max' => 5])
->setRequired(TRUE);
$this->propertyDefinitions = StreetData::propertyDefinitions();
}
return $this->propertyDefinitions;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:avoindata="https://www.hel.fi/avoindata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numberOfFeatures="7717" timeStamp="2024-11-28T11:58:56.213+02:00" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd https://www.hel.fi/avoindata https://kartta.hel.fi/ws/geoserver/avoindata/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=avoindata%3AYLRE_Katualue_alue">
<gml:featureMembers>
<avoindata:YLRE_Katualue_alue gml:id="YLRE_Katualue_alue.228">
<avoindata:kadun_nimi>Suovakuja</avoindata:kadun_nimi>
<avoindata:kayttotarkoitus>Asuntokatu</avoindata:kayttotarkoitus>
<avoindata:yllapitoluokka>I</avoindata:yllapitoluokka>
<avoindata:pituus>139.5</avoindata:pituus>
</avoindata:YLRE_Katualue_alue>
<avoindata:YLRE_Katualue_alue gml:id="YLRE_Katualue_alue.797">
<avoindata:kadun_nimi>Rauhankatu</avoindata:kadun_nimi>
<avoindata:kayttotarkoitus>Asuntokatu</avoindata:kayttotarkoitus>
<avoindata:yllapitoluokka>II</avoindata:yllapitoluokka>
<avoindata:pituus>130.3</avoindata:pituus>
</avoindata:YLRE_Katualue_alue>
<avoindata:YLRE_Katualue_alue gml:id="YLRE_Katualue_alue.809">
<avoindata:kadun_nimi>Kruunuhaankatu</avoindata:kadun_nimi>
<avoindata:kayttotarkoitus>Asuntokatu</avoindata:kayttotarkoitus>
<avoindata:yllapitoluokka>III</avoindata:yllapitoluokka>
<avoindata:pituus>72.4</avoindata:pituus>
</avoindata:YLRE_Katualue_alue>
<avoindata:YLRE_Katualue_alue gml:id="YLRE_Katualue_alue.448">
<avoindata:kadun_nimi>Sammonkatu</avoindata:kadun_nimi>
<avoindata:kayttotarkoitus>Asuntokatu</avoindata:kayttotarkoitus>
<avoindata:yllapitoluokka>III</avoindata:yllapitoluokka>
<avoindata:pituus>75.3</avoindata:pituus>
</avoindata:YLRE_Katualue_alue>
</gml:featureMembers>
</wfs:FeatureCollection>
Loading

0 comments on commit c5725e3

Please sign in to comment.