From 9f153e7630e534210321a0815c8df88d2662ebcc Mon Sep 17 00:00:00 2001 From: Benjamin Takats Date: Sat, 28 Jan 2023 21:48:20 +0100 Subject: [PATCH] osm data --- .../Commands/Map/CreateGeoJsonPolygon.php | 40 ++++++ .../Livewire/Meetup/PrepareForBtcMapItem.php | 114 ++++++++++++++++++ .../Livewire/Meetup/PrepareForBtcMapTable.php | 13 ++ .../Livewire/Tables/MeetupForBtcMapTable.php | 51 ++++++++ app/Models/City.php | 6 +- config/filesystems.php | 6 + ..._115414_add_osm_fields_to_cities_table.php | 36 ++++++ database/seeders/DatabaseSeeder.php | 13 +- resources/lang/de.json | 5 +- resources/lang/en.json | 5 +- resources/lang/es.json | 5 +- resources/lang/fr.json | 3 +- resources/lang/hr.json | 3 +- resources/lang/it.json | 3 +- resources/lang/mk.json | 3 +- resources/lang/pl.json | 3 +- resources/lang/pt.json | 3 +- resources/lang/tr.json | 3 +- .../columns/meetups/osm-actions.blade.php | 24 ++++ resources/views/layouts/app.blade.php | 2 +- .../meetup/prepare-for-btc-map-item.blade.php | 104 ++++++++++++++++ .../prepare-for-btc-map-table.blade.php | 3 + routes/web.php | 12 ++ 23 files changed, 441 insertions(+), 19 deletions(-) create mode 100644 app/Console/Commands/Map/CreateGeoJsonPolygon.php create mode 100644 app/Http/Livewire/Meetup/PrepareForBtcMapItem.php create mode 100644 app/Http/Livewire/Meetup/PrepareForBtcMapTable.php create mode 100644 app/Http/Livewire/Tables/MeetupForBtcMapTable.php create mode 100644 database/migrations/2023_01_28_115414_add_osm_fields_to_cities_table.php create mode 100644 resources/views/columns/meetups/osm-actions.blade.php create mode 100644 resources/views/livewire/meetup/prepare-for-btc-map-item.blade.php create mode 100644 resources/views/livewire/meetup/prepare-for-btc-map-table.blade.php diff --git a/app/Console/Commands/Map/CreateGeoJsonPolygon.php b/app/Console/Commands/Map/CreateGeoJsonPolygon.php new file mode 100644 index 00000000..bf22e211 --- /dev/null +++ b/app/Console/Commands/Map/CreateGeoJsonPolygon.php @@ -0,0 +1,40 @@ +with([ + 'city', + ]) + ->get(); + + foreach ($meetups as $meetup) { + dd($meetup->city->name); + } + + return Command::SUCCESS; + } +} diff --git a/app/Http/Livewire/Meetup/PrepareForBtcMapItem.php b/app/Http/Livewire/Meetup/PrepareForBtcMapItem.php new file mode 100644 index 00000000..6b8f71e0 --- /dev/null +++ b/app/Http/Livewire/Meetup/PrepareForBtcMapItem.php @@ -0,0 +1,114 @@ +get( + 'https://nominatim.openstreetmap.org/search?city='.$this->meetup->city->name.'&format=json&polygon_geojson=1' + ); + $this->osmSearchResults = $response->json(); + + $response = Http::acceptJson() + ->get( + 'https://nominatim.openstreetmap.org/search?state='.$this->meetup->city->name.'&format=json&polygon_geojson=1' + ); + $this->osmSearchResultsState = $response->json(); + + if ($this->meetup->city->osm_relation) { + $this->selectedItem = $this->meetup->city->osm_relation; + + $wikipediaUrl = 'https://query.wikidata.org/sparql?query=SELECT%20%3Fpopulation%20WHERE%20%7B%0A%20%20SERVICE%20wikibase%3Amwapi%20%7B%0A%20%20%20%20%20%20bd%3AserviceParam%20mwapi%3Asearch%20%22'.urlencode($this->meetup->city->name).'%22%20.%20%20%20%20%0A%20%20%20%20%20%20bd%3AserviceParam%20mwapi%3Alanguage%20%22en%22%20.%20%20%20%20%0A%20%20%20%20%20%20bd%3AserviceParam%20wikibase%3Aapi%20%22EntitySearch%22%20.%0A%20%20%20%20%20%20bd%3AserviceParam%20wikibase%3Aendpoint%20%22www.wikidata.org%22%20.%0A%20%20%20%20%20%20bd%3AserviceParam%20wikibase%3Alimit%201%20.%0A%20%20%20%20%20%20%3Fitem%20wikibase%3AapiOutputItem%20mwapi%3Aitem%20.%0A%20%20%7D%0A%20%20%3Fitem%20wdt%3AP1082%20%3Fpopulation%0A%7D'; + $response = Http::acceptJson() + ->get( + $wikipediaUrl + ); + $this->wikipediaSearchResults = $response->json(); + } + } + + public function selectItem($index, bool $isState = false) + { + if ($isState) { + $this->selectedItem = $this->osmSearchResultsState[$index]; + } else { + $this->selectedItem = $this->osmSearchResults[$index]; + } + Storage::disk('geo') + ->put('geojson_'.$this->selectedItem['osm_id'].'.json', + json_encode($this->selectedItem['geojson'], JSON_THROW_ON_ERROR)); + $input = storage_path('app/geo/geojson_'.$this->selectedItem['osm_id'].'.json'); + $output = storage_path('app/geo/output_'.$this->selectedItem['osm_id'].'.json'); + exec('mapshaper '.$input.' -simplify dp 4% -o '.$output); + Storage::disk('geo') + ->put( + 'trimmed_'.$this->selectedItem['osm_id'].'.json', + str(Storage::disk('geo') + ->get('output_'.$this->selectedItem['osm_id'].'.json')) + ->after('{"type":"GeometryCollection", "geometries": [') + ->beforeLast(']}') + ->toString() + ); + $this->meetup->city->osm_relation = $this->selectedItem; + $this->meetup->city->simplified_geojson = json_decode(trim(Storage::disk('geo') + ->get('trimmed_'.$this->selectedItem['osm_id'].'.json')), + false, 512, JSON_THROW_ON_ERROR); + $this->meetup->city->population = 0; + $this->meetup->city->population_date = date('Y'); + $this->meetup->city->save(); + + return to_route('osm.meetups.item', ['meetup' => $this->meetup]); + } + + public function setPercent($percent) + { + $input = storage_path('app/geo/geojson_'.$this->selectedItem['osm_id'].'.json'); + $output = storage_path('app/geo/output_'.$this->selectedItem['osm_id'].'.json'); + exec('mapshaper '.$input.' -simplify dp '.$percent.'% -o '.$output); + Storage::disk('geo') + ->put( + 'trimmed_'.$this->selectedItem['osm_id'].'.json', + str(Storage::disk('geo') + ->get('output_'.$this->selectedItem['osm_id'].'.json')) + ->after('{"type":"GeometryCollection", "geometries": [') + ->beforeLast(']}') + ->toString() + ); + $this->meetup->city->simplified_geojson = json_decode(trim(Storage::disk('geo') + ->get('trimmed_'.$this->selectedItem['osm_id'].'.json')), + false, 512, JSON_THROW_ON_ERROR); + $this->meetup->city->save(); + + return to_route('osm.meetups.item', ['meetup' => $this->meetup]); + } + + public function takePop($value) + { + $this->meetup->city->population = $value; + $this->meetup->city->population_date = date('Y'); + $this->meetup->city->save(); + + return to_route('osm.meetups.item', ['meetup' => $this->meetup]); + } + + public function render() + { + return view('livewire.meetup.prepare-for-btc-map-item'); + } +} diff --git a/app/Http/Livewire/Meetup/PrepareForBtcMapTable.php b/app/Http/Livewire/Meetup/PrepareForBtcMapTable.php new file mode 100644 index 00000000..0f09b954 --- /dev/null +++ b/app/Http/Livewire/Meetup/PrepareForBtcMapTable.php @@ -0,0 +1,13 @@ +setPrimaryKey('id') + ->setAdditionalSelects([ + 'osm_relation', + 'simplified_geojson', + 'population', + 'population_date', + ]) + ->setPerPageAccepted([ + 100000, + ]) + ->setPerPage(100000); + } + + public function columns(): array + { + return [ + Column::make("Id", "id") + ->sortable(), + Column::make("Name", "name") + ->sortable(), + Column::make("City", "city.name") + ->sortable(), + Column::make("Country", "city.country.name") + ->sortable(), + Column::make("Actions") + ->label(fn($row, Column $column) => view('columns.meetups.osm-actions', ['row' => $row])), + ]; + } + + public function builder(): Builder + { + return Meetup::query() + ->with([ + 'city.country', + ]); + } +} diff --git a/app/Models/City.php b/app/Models/City.php index 576af044..b4663f59 100644 --- a/app/Models/City.php +++ b/app/Models/City.php @@ -28,8 +28,10 @@ class City extends Model * @var array */ protected $casts = [ - 'id' => 'integer', - 'country_id' => 'integer', + 'id' => 'integer', + 'country_id' => 'integer', + 'osm_relation' => 'json', + 'simplified_geojson' => 'json', ]; protected static function booted() diff --git a/config/filesystems.php b/config/filesystems.php index e9d9dbdb..11eea8a6 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -36,6 +36,12 @@ return [ 'throw' => false, ], + 'geo' => [ + 'driver' => 'local', + 'root' => storage_path('app/geo'), + 'throw' => false, + ], + 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), diff --git a/database/migrations/2023_01_28_115414_add_osm_fields_to_cities_table.php b/database/migrations/2023_01_28_115414_add_osm_fields_to_cities_table.php new file mode 100644 index 00000000..82c8c014 --- /dev/null +++ b/database/migrations/2023_01_28_115414_add_osm_fields_to_cities_table.php @@ -0,0 +1,36 @@ +json('osm_relation') + ->nullable(); + $table->json('simplified_geojson') + ->nullable(); + $table->unsignedBigInteger('population') + ->nullable(); + $table->string('population_date') + ->nullable(); + }); + } + + /** + * Reverse the migrations. + * @return void + */ + public function down() + { + Schema::table('cities', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 992d55bd..8c5069ee 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -125,6 +125,13 @@ class DatabaseSeeder extends Seeder 'longitude' => 8.65639, 'created_by' => 1, ]); + City::create([ + 'country_id' => 1, + 'name' => 'Hessen', + 'latitude' => 50.526501, + 'longitude' => 9.004440, + 'created_by' => 1, + ]); Venue::create([ 'city_id' => 1, 'name' => 'The Blue Studio Coworking (Füssen)', @@ -376,9 +383,9 @@ Deshalb werden Sie von mir in diesem Kurs leicht verständlich an das Thema hera Artisan::call(ReadAndSyncPodcastFeeds::class); Artisan::call(SyncOpenBooks::class); Meetup::create([ - 'city_id' => 1, - 'name' => 'Einundzwanzig ' . str()->random(5), - 'telegram_link' => 'https://t.me/EinundzwanzigKempten', + 'city_id' => 6, + 'name' => 'Einundzwanzig Hessen', + 'telegram_link' => 'https://t.me/EinundzwanzigHessen', 'created_by' => 1, ]); MeetupEvent::create([ diff --git a/resources/lang/de.json b/resources/lang/de.json index 2d09f30a..2f43cfd5 100644 --- a/resources/lang/de.json +++ b/resources/lang/de.json @@ -697,5 +697,6 @@ "no location set": "kein Ort gesetzt", "Open on Youtube": "Auf Youtube öffnen", "You do not have permission to view the page.": "Du hast keine Berechtigung, die Seite anzuzeigen.", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "Bitte kontaktiere die Administratoren für neue Dateitypen, ansonsten packe die Dateien in ein ZIP! (Derzeit: PDF, ZIP)" -} + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "Bitte kontaktiere die Administratoren für neue Dateitypen, ansonsten packe die Dateien in ein ZIP! (Derzeit: PDF, ZIP)", + "load more...": "" +} \ No newline at end of file diff --git a/resources/lang/en.json b/resources/lang/en.json index 920dc66b..3561cee4 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -691,5 +691,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" -} + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" +} \ No newline at end of file diff --git a/resources/lang/es.json b/resources/lang/es.json index 270d164b..d6493625 100644 --- a/resources/lang/es.json +++ b/resources/lang/es.json @@ -691,5 +691,6 @@ "no location set": "no hay ubicación establecida", "Open on Youtube": "Abrir en Youtube", "You do not have permission to view the page.": "No tienes permiso para ver la página.", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "Si deseas nuevos tipos de archivo, pónte en contacto con los administradores; de lo contrario, envíe los archivos en un ZIP. (Actualmente: PDF, ZIP)" -} + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "Si deseas nuevos tipos de archivo, pónte en contacto con los administradores; de lo contrario, envíe los archivos en un ZIP. (Actualmente: PDF, ZIP)", + "load more...": "" +} \ No newline at end of file diff --git a/resources/lang/fr.json b/resources/lang/fr.json index 13515e55..59cbd973 100644 --- a/resources/lang/fr.json +++ b/resources/lang/fr.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/hr.json b/resources/lang/hr.json index 29f16bc8..190ba5ac 100644 --- a/resources/lang/hr.json +++ b/resources/lang/hr.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/it.json b/resources/lang/it.json index ca173b56..bba13bdc 100644 --- a/resources/lang/it.json +++ b/resources/lang/it.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/mk.json b/resources/lang/mk.json index 857fb161..c57d4b23 100644 --- a/resources/lang/mk.json +++ b/resources/lang/mk.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/pl.json b/resources/lang/pl.json index 531e5457..e7cb961e 100644 --- a/resources/lang/pl.json +++ b/resources/lang/pl.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/pt.json b/resources/lang/pt.json index 3969ede1..7bb3ae5f 100644 --- a/resources/lang/pt.json +++ b/resources/lang/pt.json @@ -692,5 +692,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/lang/tr.json b/resources/lang/tr.json index 9a40362d..8832c76a 100644 --- a/resources/lang/tr.json +++ b/resources/lang/tr.json @@ -666,5 +666,6 @@ "no location set": "", "Open on Youtube": "", "You do not have permission to view the page.": "", - "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "" + "Please contact the admins for new file types, otherwise pack the files in a ZIP! (Currently: PDF, ZIP)": "", + "load more...": "" } \ No newline at end of file diff --git a/resources/views/columns/meetups/osm-actions.blade.php b/resources/views/columns/meetups/osm-actions.blade.php new file mode 100644 index 00000000..7ba6561a --- /dev/null +++ b/resources/views/columns/meetups/osm-actions.blade.php @@ -0,0 +1,24 @@ +
+
+ @if($row->osm_relation) + has OSM relation + @endif +
+
+ population {{ $row->population }} +
+
+ @if($row->population_date) + population date {{ $row->population_date }} + @endif +
+
+ + Open OSM Item + +
+
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index a6ad5801..716d29a8 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -29,6 +29,7 @@ + @mapstyles @mapscripts @@ -37,7 +38,6 @@ @livewireStyles - @mapstyles