function geojson_geometry($item) { $geometry = json_decode(gisQuery::EWKT2GeoJSON(doctrine_value($item->get('geom_wkt')))); if ($geometry->type === 'Point' && doctrine_value($item['elevation'])) { $geometry->coordinates[] = $item['elevation']; } return $geometry; }
function makeAssociations($id_min, $id_max, $is_map = false) { $id = $id_min; while ($id <= $id_max) { echo "Computing associations for document {$id} ... \n"; // if associations with areas for current doc already existed, delete them //$deleted = Association::deleteAllFor($id, array('dr', 'dc', 'dd', 'dm')); //if ($deleted) echo "Deleted $deleted already existing associations. \n"; // compute new associations $areas = gisQuery::getAreasContaining($id); $maps = gisQuery::getMapsContaining($id); // perform association with these areas. foreach ($areas as $area) { switch ($area['type']) { case 1: // range $type = 'dr'; break; case 2: // country $type = 'dc'; break; case 3: // dept $type = 'dd'; break; } $a = new GeoAssociation(); echo "[type={$type}] found area : " . $area['id'] . "\n"; $a->doSaveWithValues($id, $area['id'], $type); // main, linked, type unset($a); } // perform association with these maps if current document is not a map. if (!$is_map) { foreach ($maps as $map) { $a = new GeoAssociation(); echo "[type=dm] found map : " . $map['id'] . "\n"; $a->doSaveWithValues($id, $map['id'], 'dm'); // main, linked, type unset($a); } } $id++; } }
/** refresh geoassociations of the route and 'sub' outings */ public function executeRefreshgeoassociations() { $referer = $this->getRequest()->getReferer(); $id = $this->getRequestParameter('id'); // check if user is moderator: done in apps/frontend/config/security.yml $document = Document::find($this->model_class, $id, array('geom')); if (!$document) { $this->setErrorAndRedirect('Document does not exist', $referer); } if (!$document->geom) { $this->setErrorAndRedirect('Cannot refresh route geoassociations for routes without geom', $referer); } $nb_created = gisQuery::createGeoAssociations($id, true, true); c2cTools::log("created {$nb_created} geo associations"); $this->refreshGeoAssociations($id); $this->clearCache('routes', $id, false, 'view'); $this->setNoticeAndRedirect('Geoassociations refreshed', "@document_by_id?module=routes&id={$id}"); }
public function executeTooltipTest() { $bbox = $this->getRequestParameter('bbox'); $layers = $this->getRequestParameter('layers'); // TODO check params $this->nb_items = 0; foreach (explode(',', $layers) as $layer) { list($module, $model, $type_where) = self::_getTooltipParamFromLayer($layer); $where = gisQuery::getQueryByBbox($bbox, 'geom', $module); $q = Doctrine_Query::create()->from("{$model} m")->where('m.redirects_to IS NULL')->addWhere($where['where_string']); if ($type_where) { $q->addWhere($type_where); } //$this->nb_items += $q->count(); TODO is it quickier to use directly count? $results = $q->execute(); $this->nb_items += count($results); // save information that can be useful in next steps if ($results->getFirst()) { $sav_model = $model; $sav_id = $results->getFirst()->getId(); } } // if only one result, directly display its name if ($this->nb_items == 1) { // specific behaviour for users: we don't want to display user name if profile // is private and user is not connected if ($sav_model == 'User' && !$this->getUser()->isConnected() && !UserPrivateData::hasPublicProfile($sav_id)) { $this->name = $this->__('not available'); } else { $langs = sfContext::getInstance()->getUser()->getPreferedLanguageList(); $i18n = Doctrine_Query::create()->select('m.culture, m.name')->from("{$sav_model}I18n m")->where('m.id = ?', array($sav_id))->execute(); $old_lang = 200; foreach ($i18n as $name) { $lang_pos = array_search($name->get('culture'), $langs); if ($lang_pos === false) { $lang_pos = 10; } // test if language is prefered over the older if ($lang_pos < $old_lang) { $old_lang = $lang_pos; $uname = $name->get('name'); } } $this->name = $uname; } } $this->setJsonResponse(); }
$map_url = '//maps.googleapis.com/maps/api/staticmap?size=310x310&maptype=terrain&mobile=true&sensor=false&key=' . sfConfig::get('app_google_api_key') . '&'; $map_options = array(); $module = $document->module; if ($module == 'summits' || $module == 'parkings' || $module == 'sites' || $module == 'huts' || $module == 'products' || $module == 'users' || $module == 'images') { $map_options[] = 'markers=shadow:false|icon:' . _marker_url($module) . '|' . $document['lat'] . ',' . $document['lon']; $map_options[] = 'zoom=12'; } elseif ($document->get('geom_wkt') && ($module == 'outings' || $module == 'routes')) { $tolerance = _compute_tolerance(gisQuery::getBox2d($document->id, $module), true); $geoms = explode('),(', gisQuery::getEWKT($document->id, true, $module, null, $tolerance)); foreach ($geoms as $geom) { $map_options[] = 'path=weight:2|color:0xffff00cc|enc:' . _polyline_encode(str_replace(array('(', ')'), '', $geom)); } } elseif ($document->get('geom_wkt') && ($module == 'maps' || $module == 'areas')) { // we cannot use donut geometries, so we instead create multiple lines $tolerance = _compute_tolerance(gisQuery::getBox2d($document->id, $module)); $geoms = gisQuery::getEWKT($document->id, true, $module, null, $tolerance); $geoms = explode('),(', $geoms); foreach ($geoms as $geom) { $map_options[] = 'path=weight:2|color:0xff0000cc|enc:' . _polyline_encode(str_replace(array('(', ')'), '', $geom)); } } // display linked summits, parkings and huts, if any $markers = array(); $nb_printed_docs = 0; foreach (array('parkings', 'summits', 'huts') as $type) { if (!isset($document->{$type})) { continue; } foreach ($document->{$type} as $doc) { if (!empty($doc['pointwkt'])) { switch ($doc['module']) {
/** summits: refresh geo associations of summit, 'sub' routes and outings */ public function updateGeoAssociations($id) { $referer = $this->getRequest()->getReferer(); $this->document = Document::find($this->model_class, $id, array('summit_type')); if (!$this->document) { $this->setErrorAndRedirect('Document does not exist', $referer); } $nb_created = gisQuery::createGeoAssociations($id, true, true); c2cTools::log("created {$nb_created} geo associations"); $this->refreshGeoAssociations($id); $this->clearCache('summits', $id, false, 'view'); $this->setNoticeAndRedirect('Geoassociations refreshed', "@document_by_id?module=summits&id={$id}"); }
<?php /** * Updates geo associations of documents contained in parameter areas. */ define('SF_ROOT_DIR', realpath(dirname(__FILE__) . '/..')); define('SF_APP', 'frontend'); define('SF_ENVIRONMENT', 'dev'); define('SF_DEBUG', true); require_once SF_ROOT_DIR . DIRECTORY_SEPARATOR . 'apps' . DIRECTORY_SEPARATOR . SF_APP . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.php'; // needed for doctrine connection to work sfContext::getInstance(); // ids of areas containing objects of whom geoassociations must be updated: $areas_ids = array(369, 379); $i = 0; foreach ($areas_ids as $id) { // find all doc associated to current area $associated_docs = GeoAssociation::findAllAssociations($id, null, 'linked'); foreach ($associated_docs as $doc) { $doc_id = $doc->get('main_id'); if (!($document = Document::find('Document', $doc_id, array('module')))) { continue; } // no maps are linked to outings, users and other maps $linkToMaps = !in_array($document->get('module'), array('outings', 'users', 'maps')); gisQuery::createGeoAssociations($doc_id, true, $linkToMaps); // TODO: handle "inherited" geo associations such as those of routes and outings $i++; } } echo "{$i} documents updated\n";
/** * Executes easy upload action * Due to a limitation in flash... only the name of the file is usable * so other informations are sent by reference... */ public function executeUpload() { $document_id = $this->getRequestParameter('document_id'); $mod = $this->getRequestParameter('mod'); $redir_route = "@document_by_id?module={$mod}&id={$document_id}"; $request = $this->getRequest(); if ($request->getMethod() == sfRequest::POST) { // check if user has the rights to upload images to the document $user = $this->getUser(); $user_id = $user->getId(); $user_valid = true; switch ($mod) { case 'users': if ($user_id != $document_id) { $user_valid = false; } break; case 'outings': if (!Association::find($user_id, $document_id, 'uo')) { $user_valid = false; } break; case 'images': $image = Document::find('Image', $document_id, array('image_type')); if (!$image) { break; } $creator = $image->getCreator(); if ($image->get('image_type') == 2 && $creator['id'] != $user_id) { $user_valid = false; } break; case 'articles': $article = Document::find('Article', $document_id, array('article_type')); if ($article->get('article_type') == 2 && !Association::find($user_id, $document_id, 'uc')) { $user_valid = false; } break; default: break; } if (!$user_valid && !$user->hasCredential('moderator')) { return $this->setErrorAndRedirect('Operation not allowed', $redir_route); } c2cTools::log('uploading files'); $temp_dir = sfConfig::get('sf_upload_dir') . DIRECTORY_SEPARATOR . sfConfig::get('app_images_temp_directory_name') . DIRECTORY_SEPARATOR; if (!is_dir($temp_dir) || !is_writable($temp_dir)) { return $this->setErrorAndRedirect('image dir unavailable', $redir_route); } $uploaded_files = $request->getFiles(); $uploaded_files = $uploaded_files['image_file']; $images_names = $this->getRequestParameter('name'); $images_categories = $this->hasRequestParameter('categories') ? $this->getRequestParameter('categories') : array(); $images_types = $this->getRequestParameter('image_type'); // Note: sfWebRequest::getFile...() methods cannot be used directy since uploaded files // are transmitted in a image[] POST var that does not fit with those methods. foreach ($uploaded_files['tmp_name'] as $key => $filename) { $unique_filename = c2cTools::generateUniqueName(); $file_ext = Images::detectExtension($filename); c2cTools::log("processing file {$unique_filename}"); // upload file in a temporary folder $new_location = $temp_dir . $unique_filename . $file_ext; c2cTools::log("moving file to {$new_location}"); if (!move_uploaded_file($filename, $new_location)) { return $this->setErrorAndRedirect('Failed moving uploaded file', $redir_route); } // svg if ($file_ext == '.svg') { if (!SVG::rasterize($temp_dir, $unique_filename, $file_ext)) { return $this->setErrorAndRedirect('Failed rasterizing svg file', $redir_route); } } // if jpg, check if we need orientation changes if ($file_ext == '.jpg') { Images::correctOrientation("{$temp_dir}{$unique_filename}{$file_ext}"); } c2cTools::log('resizing image'); // generate thumbnails (ie. resized images: "BI"/"SI") Images::generateThumbnails($unique_filename, $file_ext, $temp_dir); // retrieve image caption (name) $name = array_key_exists($key, $images_names) ? $images_names[$key] : $this->__('Give me a name'); // save image in DB and move temp files in the main dir c2cTools::log('saving image'); $activities = array(); $document = Document::find('Document', $document_id, array('id', 'module')); if (!$document) { return 0; } $model = c2cTools::module2model($document->get('module')); if (in_array($model, array('Outing', 'Article', 'Book', 'Hut', 'Image', 'Route'))) { $document = Document::find($model, $document_id, array('activities')); $activities = $document->get('activities'); } elseif ($model == 'Site') { $activities = array(4); // rock_climbing for sites by default } $image_type = $images_types[$key]; $categories = array_key_exists($key, $images_categories) ? $images_categories[$key] : array(); $image_id = Image::customSave($name, $unique_filename . $file_ext, $document_id, $user_id, $model, $activities, $categories, $image_type); $nb_created = gisQuery::createGeoAssociations($image_id, false); c2cTools::log("created {$nb_created} geo associations for image {$image_id}"); // TODO: handle errors with thumbnails generation and data saving? } // remove cache of calling page $this->clearCache($mod, $document_id, false, 'view'); // a new image has been uploaded, clear cache for images lists and whatsnew $this->clearCache('images', 0, true); return $this->setNoticeAndRedirect('image successfully uploaded', $redir_route . '#images'); } else { switch ($mod) { case 'articles': // default license depends on the article type $article = Document::find('Article', $document_id); $this->default_license = $article->get('article_type'); break; case 'books': $this->default_license = 1; break; case 'huts': $this->default_license = 1; break; case 'images': // default license is that of associated image $image = Document::find('Image', $document_id); $this->default_license = $image->get('license'); break; case 'outings': $this->default_license = 2; break; case 'parkings': $this->default_license = 1; break; case 'routes': $this->default_license = 1; break; case 'sites': $this->default_license = 1; break; case 'summits': $this->default_license = 1; break; case 'products': $this->default_license = 1; break; case 'users': $this->default_license = 2; break; default: $this->default_license = 2; } } // display form }
public static function buildBboxCondition(&$conditions, &$values, $field, $param) { /* $bbox_array = explode(',', $param); $reformatted_bbox = "$bbox_array[0] $bbox_array[1], $bbox_array[2] $bbox_array[3]"; $reformatted_field = str_replace('.', '_', $field); $conditions[] = "get_bbox('$reformatted_field', '$reformatted_bbox')"; */ $param = str_replace(array('-', '~'), array(',', ','), $param); $where = gisQuery::getQueryByBbox($param, $field); $conditions[] = $where['where_string']; }