diff --git a/lib/Controller/FavoritesController.php b/lib/Controller/FavoritesController.php index 287f67a43..0478c6405 100644 --- a/lib/Controller/FavoritesController.php +++ b/lib/Controller/FavoritesController.php @@ -229,7 +229,7 @@ public function importFavorites($path) { if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and $file->isReadable()){ $lowerFileName = strtolower($file->getName()); - if ($this->endswith($lowerFileName, '.gpx') or $this->endswith($lowerFileName, '.kml') or $this->endswith($lowerFileName, '.kmz')) { + if ($this->endswith($lowerFileName, '.gpx') or $this->endswith($lowerFileName, '.kml') or $this->endswith($lowerFileName, '.kmz') or $this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { $result = $this->favoritesService->importFavorites($this->userId, $file); return new DataResponse($result); } diff --git a/lib/Service/FavoritesService.php b/lib/Service/FavoritesService.php index 81dba7137..9a3b22a04 100644 --- a/lib/Service/FavoritesService.php +++ b/lib/Service/FavoritesService.php @@ -421,6 +421,9 @@ public function importFavorites($userId, $file) { elseif ($this->endswith($lowerFileName, '.kmz')) { return $this->importFavoritesFromKmz($userId, $file); } + elseif ($this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { + return $this->importFavoritesFromGeoJSON($userId, $file); + } } public function importFavoritesFromKmz($userId, $file) { @@ -655,6 +658,78 @@ private function gpxDataElement($parser, $data) { } } + public function importFavoritesFromGeoJSON($userId, $file) { + $this->nbImported = 0; + $this->linesFound = false; + $this->currentFavoritesList = []; + $this->importUserId = $userId; + + // Read file content + $path = $file->getStorage()->getLocalFile($file->getInternalPath()); + $fdata = file_get_contents($path); + + // Decode file content from JSON + $data = json_decode($fdata, true, 512, JSON_THROW_ON_ERROR); + + if($data == null or !array_key_exists('features', $data)) { + $this->logger->error( + 'Exception parsing '.$file->getName().': no places found to import', + array('app' => 'maps') + ); + } + + // Loop over all favorite entries + foreach($data['features'] as $key => $value) { + $this->currentFavorite = []; + + // Ensure that we have a valid GeoJSON Point geometry + if($value['geometry']['type'] !== "Point") { + $this->linesFound = true; + continue; + } + + // Read geometry + $this->currentFavorite['lng'] = floatval($value['geometry']['coordinates'][0]); + $this->currentFavorite['lat'] = floatval($value['geometry']['coordinates'][1]); + + $this->currentFavorite['name'] = $value['properties']['Title']; + $this->currentFavorite['category'] = $this->l10n->t('Personal'); + + $time = new \DateTime($value['properties']['Published']); + $this->currentFavorite['date_created'] = $time->getTimestamp(); + + $time = new \DateTime($value['properties']['Updated']); + $this->currentFavorite['date_modified'] = $time->getTimestamp(); + + if(array_key_exists('Address', $value['properties']['Location'])) { + $this->currentFavorite['comment'] = $value['properties']['Location']['Address']; + } + + + // Store this favorite + array_push($this->currentFavoritesList, $this->currentFavorite); + $this->nbImported++; + + // if we have enough favorites, we create them and clean the array + if (count($this->currentFavoritesList) >= 500) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + unset($this->currentFavoritesList); + $this->currentFavoritesList = []; + } + } + + // Store last set of favorites + if (count($this->currentFavoritesList) > 0) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + } + unset($this->currentFavoritesList); + + return [ + 'nbImported'=>$this->nbImported, + 'linesFound'=>$this->linesFound + ]; + } + private function endswith($string, $test) { $strlen = strlen($string); $testlen = strlen($test); diff --git a/src/favoritesController.js b/src/favoritesController.js index f304cab1c..8454adb21 100644 --- a/src/favoritesController.js +++ b/src/favoritesController.js @@ -202,12 +202,12 @@ FavoritesController.prototype = { // import favorites $('body').on('click', '#import-favorites', function(e) { OC.dialogs.filepicker( - t('maps', 'Import favorites from gpx (OsmAnd, Nextcloud Maps) or kmz/kml (F-Droid Maps, Maps.me, Marble)'), + t('maps', 'Import favorites from GeoJSON (Google Maps), gpx (OsmAnd, Nextcloud Maps) or kmz/kml (F-Droid Maps, Maps.me, Marble)'), function(targetPath) { that.importFavorites(targetPath); }, false, - ['application/gpx+xml', 'application/vnd.google-earth.kmz', 'application/vnd.google-earth.kml+xml'], + ['application/gpx+xml', 'application/vnd.google-earth.kmz', 'application/vnd.google-earth.kml+xml', 'application/json', 'application/geo+json'], true ); }); diff --git a/src/filetypes.js b/src/filetypes.js index 834bbbde6..1bff2c775 100644 --- a/src/filetypes.js +++ b/src/filetypes.js @@ -100,6 +100,15 @@ $(document).ready(function() { iconClass: 'icon-maps-black', actionHandler: importFavoritesFile }); + // import geojson files as favorites + OCA.Files.fileActions.registerAction({ + name: 'importGeoJsonFavoritesMaps', + displayName: t('maps', 'Import as favorites in Maps'), + mime: 'application/geo+json', + permissions: OC.PERMISSION_READ, + iconClass: 'icon-maps-black', + actionHandler: importFavoritesFile + }); // import gpx files as devices OCA.Files.fileActions.registerAction({ diff --git a/templates/navigation/index.php b/templates/navigation/index.php index 086456d2e..78216045c 100644 --- a/templates/navigation/index.php +++ b/templates/navigation/index.php @@ -22,7 +22,7 @@