// needed for doctrine connection to work sfContext::getInstance(); // Next Step : retrieve highest summits associated (in fact there should always be only one) with routes, and transfer summit geoassociations to route. // WARNING: set correct id limits // WARNING 2: routes must be consecutive. $id = 44918; $id_max = 57877; while ($id <= $id_max) { echo "Computing associations for route {$id} ... \n"; // if associations with areas for current doc already existed, delete them //$deleted = GeoAssociation::deleteAllFor($id, array('dr', 'dc', 'dd', 'dm')); //if ($deleted) echo "Deleted $deleted already existing geoassociations. \n"; // get all associated regions (3+maps) with this summit: //$summit_id is the id of associated summit with route $id $associated_docs = Association::findAllAssociatedDocs($id, array('id', 'module'), 'sr'); // summit-route foreach ($associated_docs as $doc) { if ($doc['module'] == 'summits') { $summit_id = $doc['id']; } } $associations = GeoAssociation::findAllAssociations($summit_id, array('dr', 'dc', 'dd', 'dm')); // replicate them with route_id instead of summit_id: foreach ($associations as $ea) { $a = new GeoAssociation(); $a->doSaveWithValues($id, $ea->get('linked_id'), $ea->get('type')); echo "Created association with " . $ea->get('linked_id') . " \n"; unset($a); } $id++; }
protected function endEdit() { //Test if form is submitted or not if ($this->success) { // if this is the first version of the outing (aka creation) // set a flash message to encourage to also enhance the corresponding route if (is_null($this->document->getVersion())) { $this->setNotice('thanks for new outing'); } // try to perform association with linked_doc (if pertinent) $associated_id = $this->getRequestParameter('document_id'); $user_id = $this->getUser()->getId(); $id = $this->document->get('id'); if ($this->new_document && $associated_id || $associated_id && !Association::find($associated_id, $id)) { // we must get this document's module (site or route ?) $associated_doc = Document::find('Document', $associated_id, array('module')); if ($associated_doc) { $associated_module = $associated_doc->get('module'); $a = new Association(); if ($associated_module == 'routes') { $a->doSaveWithValues($associated_id, $id, 'ro', $user_id); // main, linked, type // clear cache of associated route ... $this->clearCache('routes', $associated_id, false, 'view'); } elseif ($associated_module == 'sites') { $a->doSaveWithValues($associated_id, $id, 'to', $user_id); // main, linked, type // clear cache of associated site ... $this->clearCache('sites', $associated_id, false, 'view'); } // here if we have created a new document and if $this->document->get('geom_wkt') is null, then use associated doc geom associations: // this allows us to filter on ranges even if no GPX is uploaded if ($this->new_document && $associated_id && !$this->document->get('geom_wkt')) { // get all associated regions (only regions, countries, depts, no maps !) with this summit: $associations = GeoAssociation::findAllAssociations($associated_id, array('dr', 'dc', 'dd', 'dv')); // replicate them with outing_id instead of (route_id or site_id): foreach ($associations as $ea) { $areas_id = $ea->get('linked_id'); $a = new GeoAssociation(); $a->doSaveWithValues($id, $areas_id, $ea->get('type')); // clear cache of associated areas $this->clearCache('areas', $areas_id, false, 'view'); } } } } // create also association with current user. if ($this->new_document) { $uo = new Association(); $uo->doSaveWithValues($user_id, $id, 'uo', $user_id); // main, linked, type // clear cache of current user $this->clearCache('users', $user_id, false, 'view'); } // create association with MW contest article, if requested if ($this->new_document) { $mw_contest_associate = $this->getRequestParameter('mw_contest_associate'); if ($mw_contest_associate) { $mw_article_id = sfConfig::get('app_mw_contest_id'); $oc = new Association(); $oc->doSaveWithValues($id, $mw_article_id, 'oc', $user_id); } } parent::endEdit(); // redirect to document view } }
/** * Overriddes the one in parent class * this is because we sometimes have to do things when centroid coordinates have moved. */ protected function refreshGeoAssociations($id) { c2cTools::log("Entering refreshGeoAssociations for outings linked with route {$id}"); $associated_outings = Association::findAllAssociatedDocs($id, array('id', 'geom_wkt'), 'ro'); if (count($associated_outings)) { $geoassociations = GeoAssociation::findAllAssociations($id, null, 'main'); // we create new associations : // (and delete old associations before creating the new ones) // (and do not create outings-maps associations) foreach ($associated_outings as $outing) { $i = $outing['id']; if (!$outing['geom_wkt']) { // replicate geoassoces from doc $id to outing $i and delete previous ones // (because there might be geoassociations created by this same process) // and we do not replicate map associations to outings $nb_created = GeoAssociation::replicateGeoAssociations($geoassociations, $i, true, false); c2cTools::log("created {$nb_created} geo associations for outing N° {$i}"); $this->clearCache('outings', $i, false, 'view'); } } } }
/** * Overriddes the one in parent class * this is because we sometimes have to do things when centroid coordinates have moved. * TODO hutsActions::endEdit() should be factorized with this.. */ protected function refreshGeoAssociations($id) { // don't refresh associated doc if summit type is "raid" if ($this->document->get('summit_type') == 5) { return; } c2cTools::log("Entering refreshGeoAssociations for routes linked with summit {$id}"); $associated_routes = Association::findAllAssociatedDocs($id, array('id', 'geom_wkt'), 'sr'); if (count($associated_routes)) { $geoassociations = GeoAssociation::findAllAssociations($id, null, 'main'); // we create new associations : // (and delete old associations before creating the new ones) // (and do not create outings-maps associations) foreach ($associated_routes as $route) { $i = $route['id']; if (!$route['geom_wkt']) { // replicate geoassoces from doc $id to outing $i and delete previous ones // (because there might be geoassociations created by this same process) $nb_created = GeoAssociation::replicateGeoAssociations($geoassociations, $i, true, true); c2cTools::log("created {$nb_created} geo associations for route N° {$i}"); $this->clearCache('routes', $i, false, 'view'); $associated_outings = Association::findAllAssociatedDocs($i, array('id', 'geom_wkt'), 'ro'); if (count($associated_outings)) { $geoassociations2 = GeoAssociation::findAllAssociations($i, null, 'main'); // we create new associations : // (and delete old associations before creating the new ones) // (and do not create outings-maps associations) foreach ($associated_outings as $outing) { $j = $outing['id']; if (!$outing['geom_wkt']) { // replicate geoassoces from doc $id to outing $i and delete previous ones // (because there might be geoassociations created by this same process) $nb_created = GeoAssociation::replicateGeoAssociations($geoassociations2, $j, true, false); c2cTools::log("created {$nb_created} geo associations for outing N° {$j}"); $this->clearCache('outings', $j, false, 'view'); } } } } } } }
function update_document() { global $argv, $argc, $conn, $comment, $is_map, $is_new_document, $culture, $name, $map_editor, $newgeom, $map_scale, $map_code, $region_type, $newgeomtext, $no_oldgeom, $oldgeom, $document_id, $prgmsg, $fullwipe, $keepassociations; if ($argc < 5) { usage(); } if ($argv[2] != 'area' && $argv[2] != 'map') { usage(); } $is_map = $argv[2] === 'map'; if (!file_exists($argv[3])) { info("Kml file does not exist\n\n"); usage(); } if (!is_numeric($argv[4])) { info("Invalid region or map id\n\n"); usage(); } $document_id = intval($argv[4]); $fullwipe = $argc === 6 && $argv[5] === 'fullwipe'; $keepassociations = $argc === 6 && $argv[5] === 'keepassociations'; $is_new_document = false; info("Create geometry from kml file...\n"); $newgeomtext = text_geometry_from_file($argv[3]); $newgeom = geometry_from_text($newgeomtext); info("Validating geometry...\n"); // check that the new geometry is valid if (!validate_geometry($newgeom)) { die("The new geometry is invalid. Aborting...\n"); } // we need to first delete old geometry and old geaoassociations $oldgeom = $conn->standaloneQuery('SELECT geom FROM ' . ($is_map ? 'maps' : 'areas') . ' WHERE id=?', array($document_id))->fetchAll(); // check that document exists if (!count($oldgeom)) { die("Specified {$argv[2]} ({$document_id}) does not exist\n"); } // Output warning if document has no geometry $oldgeom = $oldgeom[0]['geom']; if (is_null($oldgeom)) { $no_oldgeom = true; info("Warning: specified {$argv[2]} ({$document_id}) has no geometry...\n"); } else { $no_oldgeom = false; } // first, remove geometry in a separate transaction if we are to update it // no better way found... if (!$no_oldgeom) { info("Deleting old geometry...\n"); try { $conn->beginTransaction(); $history_metadata = new HistoryMetadata(); $history_metadata->setComment('Delete geometry before update'); $history_metadata->set('is_minor', false); $history_metadata->set('user_id', 2); // C2C user $history_metadata->save(); $area = Document::find($is_map ? 'Map' : 'Area', $document_id); $area->set('geom_wkt', null); $area->save(); $conn->commit(); } catch (Exception $e) { $conn->rollback(); throw $e; } info("Old geometry deleted\n"); } // then delete geoassociations // We only delete geoassociations where it is needed // ie the parts of the old geometry that does not intersect with the new one // If document has no previous geometry, we make sure to delete geoassociations // rq: we only use buffer for areas, not for maps if ($keepassociations) { // do nothing } else { if ($no_oldgeom || $fullwipe) { $geoassociations = GeoAssociation::findAllAssociations($document_id, null, 'both'); $prgmsg = "Delete all old geoassociations..."; info($prgmsg); try { $conn->beginTransaction(); $tot = count($geoassociations); foreach ($geoassociations as $i => $geoassociation) { progression($i, $tot); $geoassociation->delete(); } $conn->commit(); if (isset($deleted)) { associations_result($deleted, false); } } catch (exception $e) { $conn->rollback(); throw $e; } info("\n"); } else { $deletegeom = $conn->standaloneQuery("SELECT ST_Difference('{$oldgeom}', '{$newgeom}')")->fetchAll(); $deletegeomb = $conn->standaloneQuery("SELECT ST_Difference(buffer('{$oldgeom}', 200), buffer('{$newgeom}', 200))")->fetchAll(); $deletegeom = $deletegeom[0]['st_difference']; $deletegeomb = $deletegeomb[0]['st_difference']; // for maps, we don't use buffer at all if ($is_map) { $deletegeomb = $deletegeom; } $queries = array(); // point geometry $queries[] = array("SELECT id, module FROM documents WHERE geom && '{$deletegeomb}' " . "AND ST_Within(geom, '{$deletegeomb}') " . "AND module IN('summits', 'huts', 'sites', 'parkings', 'products', 'portals', 'images'" . ($is_map ? '' : ", 'users'") . ')', array()); $queries[] = array("SELECT id, module FROM documents WHERE geom && '{$deletegeomb}' " . "AND ST_Intersects(geom, '{$deletegeomb}') AND module" . ($is_map ? "='routes'" : " IN('routes', 'outings')"), array()); // for maps areas associations, we always compute 'full wipe', without buffer $queries[] = array("SELECT id, module FROM documents WHERE geom && '{$oldgeom}' " . "AND ST_Intersects(geom, '{$oldgeom}') AND module='" . ($is_map ? 'areas' : 'maps') . "'", array($document_id, $document_id)); $results_a = array(); foreach ($queries as $query) { $results_a[] = sfDoctrine::connection()->standaloneQuery($query[0], $query[1])->fetchAll(); } $results = array(); foreach ($results_a as $results_set) { foreach ($results_set as $d) { $results[] = $d; } } $tot = count($results); $prgmsg = "Delete obsolete geoassociations..."; info($prgmsg); try { $conn->beginTransaction(); foreach ($results as $i => $d) { progression($i, $tot); $geoassociation = GeoAssociation::find($document_id, $d['id'], null, false); if ($geoassociation !== false) { $geoassociation->delete(); $deleted[$d['module']] = isset($deleted[$d['module']]) ? $deleted[$d['module']] + 1 : 1; } // for routes and outings, we need to check that they are not intersecting the new geom // because they shouldn't be unlinked in that case // (it's quite unconvenient, but no best way found) if (in_array($d['module'], array('outings', 'routes'))) { $query = "SELECT ST_Intersects(geom, ST_Buffer('{$newgeom}', 200)) FROM " . $d['module'] . " WHERE id=?"; $result = sfDoctrine::connection()->standaloneQuery($query, array($d['id']))->fetchAll(); $result = $result[0]['st_intersects']; if ($result) { continue; } } // inherited docs: we delete geoassociations for the 'inherited docs' from sites, routes and summits // but not if they already have a geometry (gps track) switch ($d['module']) { case 'sites': case 'routes': if ($is_map) { break; } // maps are not linked to outings $associated_outings = Association::findAllAssociatedDocs($d['id'], array('id', 'geom_wkt'), $d['module'] === 'routes' ? 'ro' : 'to'); if (count($associated_outings)) { foreach ($associated_outings as $outing) { if (!$outing['geom_wkt']) { $geoassociation = GeoAssociation::find($document_id, $outing['id'], null, false); if ($geoassociation !== false) { $geoassociation->delete(); $deleted['outings'] = isset($deleted['outings']) ? $deleted['outings'] + 1 : 1; } } } } break; case 'summits': // if summit is of type raid, we should not try to update its routes and outings summit_type=5 $summit = Document::find('Summit', $d['id']); if ($summit->get('summit_type') == 5) { break; } $associated_routes = Association::findAllAssociatedDocs($d['id'], array('id', 'geom_wkt'), 'sr'); if (count($associated_routes)) { foreach ($associated_routes as $route) { $i = $route['id']; if (!$route['geom_wkt']) { $geoassociation = GeoAssociation::find($i, $document_id, null, false); if ($geoassociation !== false) { $geoassociation->delete(); $deleted['routes'] = isset($deleted['routes']) ? $deleted['routes'] + 1 : 1; } if (!$is_map) { $associated_outings = Association::findAllAssociatedDocs($i, array('id', 'geom_wkt'), 'ro'); if (count($associated_outings)) { foreach ($associated_outings as $outing) { $j = $outing['id']; if (!$outing['geom_wkt']) { $geoassociation = GeoAssociation::find($j, $document_id, null, false); if ($geoassociation !== false) { $geoassociation->delete(); $deleted['outings'] = isset($deleted['outings']) ? $deleted['outings'] + 1 : 1; } } } } } } } } break; } } info("\n"); $conn->commit(); if (isset($deleted)) { associations_result($deleted, false); } } catch (exception $e) { $conn->rollback(); throw $e; } } } // import new geometry into database and create geoassociations import_new_geometry(); }
public function executeAddroute() { $id = $this->getRequestParameter('document_id'); // check if a summit is already associated to hut. if not, create it $create_summit = Association::countMains($id, 'sh') == 0; if ($create_summit) { $document = Document::find('Hut', $id, array('elevation', 'geom_wkt')); $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); // create first version of document, with culture and geometry of hut document $hut_elevation = $document['elevation']; $hut_lat = $document['lat']; $hut_lon = $document['lon']; $hut_culture = $document->getCulture(); $hut_name = $document['name']; $history_metadata = new HistoryMetadata(); $history_metadata->setComment($this->__('Created summit synchronized with hut for access')); $history_metadata->set('is_minor', false); $history_metadata->set('user_id', 2); // C2C user $history_metadata->save(); $summit = new Summit(); $summit->setCulture($hut_culture); $summit->set('name', $hut_name); $summit->set('elevation', $hut_elevation); $summit->set('summit_type', 100); // set summit type to ' hut' $summit->set('lat', $hut_lat); $summit->set('lon', $hut_lon); $summit->save(); $conn->commit(); // add others culture versions foreach ($document->get('HutI18n') as $i18n) { $culture = $i18n->getCulture(); if ($culture != $hut_culture) { $conn->beginTransaction(); $hut_name = $i18n->getName(); $history_metadata = new HistoryMetadata(); $history_metadata->setComment($this->__('Created summit synchronized with hut for access')); $history_metadata->set('is_minor', false); $history_metadata->set('user_id', 2); // C2C user $history_metadata->save(); $summit->setCulture($culture); $summit->set('name', $hut_name); $summit->save(); $conn->commit(); } } } catch (Exception $e) { $conn->rollback(); return $this->setErrorAndRedirect($this->__('Failed to create synchronized summit'), "routes/edit?link={$summit_id}"); } $summit_id = $summit->get('id'); // get all associated regions (3+maps) with this hut: $associations = GeoAssociation::findAllAssociations($id, array('dr', 'dc', 'dd', 'dv', 'dm')); // replicate them with summit_id instead of id: foreach ($associations as $ea) { $a = new GeoAssociation(); $a->doSaveWithValues($summit_id, $ea->get('linked_id'), $ea->get('type')); } // associate hut to summit $asso = new Association(); $asso->doSaveWithValues($summit_id, $id, 'sh', 2); // C2C user } else { $associations = Association::findAllAssociations($id, 'sh'); $summit_id = $associations[0]->get('main_id'); } $this->clearCache('huts', $id); return $this->redirect("routes/edit?link={$summit_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";
//$route_id is the id of associated route with outing $id $associated_docs = Association::findAllAssociatedDocs($id, array('id', 'module'), 'ro'); if (!empty($associated_docs)) { foreach ($associated_docs as $doc) { if ($doc['module'] == 'routes') { $doc_id = $doc['id']; } } } else { $associated_docs = Association::findAllAssociatedDocs($id, array('id', 'module'), 'to'); foreach ($associated_docs as $doc) { if ($doc['module'] == 'sites') { $doc_id = $doc['id']; } } } if ($doc_id) { $associations = GeoAssociation::findAllAssociations($doc_id, array('dr', 'dc', 'dd')); // replicate them with outing_id instead of route_id: // Note: map associations are not transfered foreach ($associations as $ea) { $a = new GeoAssociation(); $a->doSaveWithValues($id, $ea->get('linked_id'), $ea->get('type')); echo "Created association with " . $ea->get('linked_id') . " \n"; unset($a); } unset($ea); } $id++; //echo 'Memory consumption: ' . number_format(memory_get_usage()) . " bytes\n"; }