Browse Source

Ajoute le group by communes dans l’outil osmose

master
vincent 1 week ago
parent
commit
d768131dea
3 changed files with 212 additions and 65 deletions
  1. +14
    -0
      lib/OSM/Element/Member/Relation.php
  2. +187
    -65
      src/Controller/ToolsController.php
  3. +11
    -0
      src/Form/OsmoseToolType.php

+ 14
- 0
lib/OSM/Element/Member/Relation.php View File

@ -0,0 +1,14 @@
<?php
namespace OSM\Element\Member;
use OSM\Element\Member\Way;
use OSM\Point;
class Relation extends Member
{
public function completeFromArray(array $array): static
{
return $this;
}
}

+ 187
- 65
src/Controller/ToolsController.php View File

@ -96,8 +96,9 @@ class ToolsController extends AbstractController
public function osmose(
Request $request,
OsmoseClient $osmose,
OverpassClient $overpass,
): Response {
$form = $this->createForm(OsmoseToolType::class, $request->query->all());
$form = $this->createForm(OsmoseToolType::class, array_merge(['limit' => 500], $request->query->all()));
$form->add('submit', SubmitType::class, ['label' => 'Générer']);
$form->handleRequest($request);
@ -106,10 +107,10 @@ class ToolsController extends AbstractController
'item' => $form->get('item')->getData(),
'source' => $form->get('source')->getData(),
'class' => $form->get('class')->getData(),
'limit' => $form->get('limit')->getData(),
'username' => '',
'bbox' => '',
'full' => 'true',
'limit' => 500,
]);
$response = new StreamedResponse();
@ -123,85 +124,206 @@ class ToolsController extends AbstractController
)
);
$features = json_decode($issues, true)['features'];
$issuesGeojson = \GeoJson\GeoJson::jsonUnserialize(json_decode($issues, true));
$groupByCity = (bool) $form->get('group_by_city')->getData();
if ($groupByCity) {
$minLat = null;
$maxLat = null;
$minLon = null;
$maxLon = null;
foreach ($issuesGeojson->getFeatures() as $feature) {
$geometry = $feature->getGeometry();
$coordinates = $geometry->getCoordinates();
$lat = (float) $coordinates[1];
$lon = (float) $coordinates[0];
if (is_null($minLat) or ($lat < $minLat)) {
$minLat = $lat;
}
if (is_null($maxLat) or ($lat > $maxLat)) {
$maxLat = $lat;
}
if (is_null($minLon) or ($lon < $minLon)) {
$minLon = $lon;
}
if (is_null($maxLon) or ($lon > $maxLon)) {
$maxLon = $lon;
}
}
$response->setCallback(function () use ($features): void {
$headings = [
'name',
'description',
'osm',
'geojson',
'status',
];
$citiesData = $overpass->query(sprintf('relation[admin_level=8][boundary=administrative]["ref:INSEE"](%f,%f,%f,%f);', $minLat, $minLon, $maxLat, $maxLon));
$citiesOsm = \OSM\OSM::createFromJson($citiesData);
$cities = [];
foreach ($citiesOsm->elements as $cityOsm) {
$geojson = \OSM\GeoJsonConverter::convertRelationToPolygon($cityOsm);
$geojsonString = '{"type":"FeatureCollection","features":[{"type": "Feature","properties":{},"geometry":'.json_encode($geojson->jsonSerialize()).'}]}';
$polygon = \geoPHP::load($geojsonString, 'json');
$cities[] = [
'name' => $cityOsm->getTagValue('name'),
'polygon' => $polygon,
'geojson' => $geojsonString,
'features' => [],
];
}
$csv = fopen('php://output', 'a');
foreach ($issuesGeojson->getFeatures() as $feature) {
$point = \geoPHP::load(json_encode($feature->jsonSerialize()), 'json');
foreach ($cities as $cityIndex => $city) {
$isIn = $city['polygon']->contains($point);
if ($isIn) {
$cities[$cityIndex]['features'][] = $feature;
}
}
}
fputcsv($csv, $headings);
$cities = array_filter($cities, function ($city) { return !empty($city['features']); });
$response->setCallback(function () use ($cities): void {
$headings = [
'name',
'description',
'osm',
'geojson',
'status',
];
$csv = fopen('php://output', 'a');
fputcsv($csv, $headings);
foreach ($cities as $city) {
$name = $city['name'];
$description = sprintf('**%d** signalements sur la commune **%s** :'.PHP_EOL.PHP_EOL, count($city['features']), $city['name']);
$geojson = $city['geojson'];
$nodes = [];
foreach ($city['features'] as $featureIndex => $feature) {
$properties = $feature->getProperties();
$description .= sprintf('* Signalement %s %s'.PHP_EOL, $properties['uuid'], $properties['title']);
if (isset($properties['fixes'])) {
$tags = [];
foreach ($properties['fixes'] as $fixItems) {
foreach ($fixItems as $fixItem) {
$isExpected = (
('N' === $fixItem['type'])
and array_key_exists('create', $fixItem)
);
if (!$isExpected) {
continue;
} // TODO gérer tous les cas possibles ici
foreach ($fixItem['create'] as $k => $v) {
$tags[$k] = $v;
}
}
}
$total = count($features);
foreach ($features as $index => $feature) {
$name = sprintf('%s n°%d/%d', $feature['properties']['title'], $index + 1, $total);
$description = <<<EOT
### Issue {$feature['properties']['uuid']}
$geometry = $feature->getGeometry();
$coordinates = $geometry->getCoordinates();
$nodes[] = [
'type' => 'node',
'id' => -1 * ($featureIndex + 1),
'lat' => (float) $coordinates[1],
'lon' => (float) $coordinates[0],
'tags' => $tags,
];
}
}
if (!empty($nodes)) {
$osm = \OSM\OSM::createFromArray([
'elements' => $nodes,
]);
} else {
$osm = '';
}
* Level {$feature['properties']['level']}
* Item {$feature['properties']['item']}
* Identifiant de source {$feature['properties']['source_id']}
* Identifiant de classe {$feature['properties']['class']}
fputcsv($csv, [
$name,
$description,
$osm,
$geojson,
'todo',
]);
}
fclose($csv);
});
} else {
$response->setCallback(function () use ($issuesGeojson): void {
$headings = [
'name',
'description',
'osm',
'geojson',
'status',
];
$csv = fopen('php://output', 'a');
fputcsv($csv, $headings);
$total = $issuesGeojson->count();
foreach ($issuesGeojson->getFeatures() as $index => $feature) {
$properties = $feature->getProperties();
$name = sprintf('%s n°%d/%d', $properties['title'], $index + 1, $total);
$description = <<<EOT
### Signalement {$properties['uuid']}
* Niveau {$properties['level']}
* Thème {$properties['item']}
* Identifiant de source {$properties['source_id']}
* Identifiant de classe {$properties['class']}
### Osmose
[ Fait](https://osmose.openstreetmap.fr/api/0.3/issue/{$feature['properties']['uuid']}/done)
[ Faux positif](https://osmose.openstreetmap.fr/api/0.3/issue/{$feature['properties']['uuid']}/false)
[ Fait](https://osmose.openstreetmap.fr/api/0.3/issue/{$properties['uuid']}/done)
[ Faux positif](https://osmose.openstreetmap.fr/api/0.3/issue/{$properties['uuid']}/false)
EOT;
if (isset($feature['properties']['fixes'])) {
$tags = [];
foreach ($feature['properties']['fixes'] as $fixItems) {
foreach ($fixItems as $fixItem) {
$isExpected = (
('N' === $fixItem['type'])
and array_key_exists('create', $fixItem)
);
if (!$isExpected) {
continue;
} // TODO gérer tous les cas possibles ici
foreach ($fixItem['create'] as $k => $v) {
$tags[$k] = $v;
if (isset($properties['fixes'])) {
$tags = [];
foreach ($properties['fixes'] as $fixItems) {
foreach ($fixItems as $fixItem) {
$isExpected = (
('N' === $fixItem['type'])
and array_key_exists('create', $fixItem)
);
if (!$isExpected) {
continue;
} // TODO gérer tous les cas possibles ici
foreach ($fixItem['create'] as $k => $v) {
$tags[$k] = $v;
}
}
}
$geometry = $feature->getGeometry();
$coordinates = $geometry->getCoordinates();
$osm = \OSM\OSM::createFromArray([
'elements' => [[
'type' => 'node',
'id' => -1,
'lat' => (float) $coordinates[1],
'lon' => (float) $coordinates[0],
'tags' => $tags,
]],
]);
} else {
$osm = '';
}
$osm = \OSM\OSM::createFromArray([
'elements' => [[
'type' => 'node',
'id' => -1,
'lat' => (float) $feature['geometry']['coordinates'][1],
'lon' => (float) $feature['geometry']['coordinates'][0],
'tags' => $tags,
]],
fputcsv($csv, [
$name,
$description,
$osm,
json_encode($feature->jsonSerialize()),
'todo',
]);
} else {
$osm = '';
}
$geojson = json_encode([
'type' => 'FeatureCollection',
'features' => [
$feature,
],
]);
fputcsv($csv, [
$name,
$description,
$osm,
$geojson,
'todo',
]);
}
fclose($csv);
});
fclose($csv);
});
}
return $response;
}


+ 11
- 0
src/Form/OsmoseToolType.php View File

@ -3,6 +3,7 @@
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
@ -13,6 +14,8 @@ class OsmoseToolType extends AbstractType
$builder
->add('item', IntegerType::class, [
'label' => 'Item',
'help_html' => true,
'help' => 'Voir la liste sur <a href="https://wiki.openstreetmap.org/wiki/FR:Osmose/issues" target="_blank">le wiki</a>',
])
->add('source', IntegerType::class, [
'label' => 'Identifiant source',
@ -20,6 +23,14 @@ class OsmoseToolType extends AbstractType
->add('class', IntegerType::class, [
'label' => 'Identifiant de la classe',
])
->add('limit', IntegerType::class, [
'label' => 'Limite',
'help' => 'Nombre mmaximal de signalements à renvoyer',
])
->add('group_by_city', CheckboxType::class, [
'label' => 'Grouper par commune',
'required' => false,
])
;
}
}

Loading…
Cancel
Save