. */ use PDO; use PDOException; use Zend_Session; /** * Class googlemap_WT_Module * * @link http://www.google.com/permissions/guidelines.html * * "... an unregistered Google Brand Feature should be followed by * the superscripted letters TM or SM ..." * * Hence, use "Google Maps™" * * "... Use the trademark only as an adjective" * * "... Use a generic term following the trademark, for example: * GOOGLE search engine, Google search" * * Hence, use "Google Maps™ mapping service" where appropriate. */ class googlemap_WT_Module extends Module implements ModuleConfigInterface, ModuleTabInterface { /** {@inheritdoc} */ public function __construct() { parent::__construct(); // Create GM tables, if not already present try { Database::updateSchema(WT_ROOT . WT_MODULES_DIR . '/googlemap/db_schema/', 'GM_SCHEMA_VERSION', 5); } catch (PDOException $ex) { // The schema update scripts should never fail. If they do, there is no clean recovery. FlashMessages::addMessage($ex->getMessage(), 'danger'); header('Location: ' . WT_BASE_URL . 'site-unavailable.php'); throw $ex; } // Set default values try { // TODO: do this once only, in a db_schema upgrade script? $this->setSetting('GM_MAP_TYPE', $this->getSetting('GM_MAP_TYPE', 'G_NORMAL_MAP')); // G_PHYSICAL_MAP, G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP $this->setSetting('GM_MAX_ZOOM', $this->getSetting('GM_MAX_ZOOM', '20')); // max zoom level $this->setSetting('GM_MIN_ZOOM', $this->getSetting('GM_MIN_ZOOM', '2')); // min zoom level $this->setSetting('GM_PRECISION_0', $this->getSetting('GM_PRECISION_0', '0')); // Country level $this->setSetting('GM_PRECISION_1', $this->getSetting('GM_PRECISION_1', '1')); // State level $this->setSetting('GM_PRECISION_2', $this->getSetting('GM_PRECISION_2', '2')); // City level $this->setSetting('GM_PRECISION_3', $this->getSetting('GM_PRECISION_3', '3')); // Neighborhood level $this->setSetting('GM_PRECISION_4', $this->getSetting('GM_PRECISION_4', '4')); // House level $this->setSetting('GM_PRECISION_5', $this->getSetting('GM_PRECISION_5', '5')); // Max prcision level $this->setSetting('GM_XSIZE', $this->getSetting('GM_XSIZE', '600')); // X-size of Google map $this->setSetting('GM_YSIZE', $this->getSetting('GM_YSIZE', '400')); // Y-size of Google map $this->setSetting('GM_PH_XSIZE', $this->getSetting('GM_PH_XSIZE', '500')); // X-size of Place Hierarchy Google map $this->setSetting('GM_PH_YSIZE', $this->getSetting('GM_PH_YSIZE', '350')); // Y-size of Place Hierarchy Google map $this->setSetting('GM_PH_MARKER', $this->getSetting('GM_PH_MARKER', 'G_FLAG')); // Possible values: G_FLAG = Flag, G_DEFAULT_ICON = Standard icon $this->setSetting('GM_DISP_SHORT_PLACE', $this->getSetting('GM_DISP_SHORT_PLACE', '0')); // Display full place name or only the actual level name } catch (\Exception $ex) { // Perhaps the module hasn't been installed yet (no entry in wt_modules) } } /** {@inheritdoc} */ public function getTitle() { return /* I18N: The name of a module. Google Maps™ is a trademark. Do not translate it? http://en.wikipedia.org/wiki/Google_maps */ I18N::translate('Google Maps™'); } /** {@inheritdoc} */ public function getDescription() { return /* I18N: Description of the “Google Maps™” module */ I18N::translate('Show the location of places and events using the Google Maps™ mapping service.'); } /** {@inheritdoc} */ public function modAction($mod_action) { switch ($mod_action) { case 'admin_config': $this->config(); break; case 'flags': $this->flags(); break; case 'pedigree_map': $this->pedigreeMap(); break; case 'admin_placecheck': $this->adminPlaceCheck(); break; case 'admin_places': $this->adminPlaces(); break; case 'places_edit': $this->placesEdit(); break; case 'wt_street_view': $this->wtStreetView(); break; default: http_response_code(404); break; } } /** {@inheritdoc} */ public function getConfigLink() { return 'module.php?mod=' . $this->getName() . '&mod_action=admin_config'; } /** {@inheritdoc} */ public function defaultTabOrder() { return 80; } /** {@inheritdoc} */ public function getPreLoadContent() { ob_start(); ?> checkMapData()) { ob_start(); echo ''; echo '
'; echo ''; echo ''; echo ''; echo '
'; echo '
'; if (Auth::isAdmin()) { echo ''; echo ''; echo ''; echo ''; echo '
'; echo '', I18N::translate('Google Maps™ preferences'), ''; echo ''; echo '', I18N::translate('Geographic data'), ''; echo ''; echo '', I18N::translate('Place check'), ''; echo '
'; } echo '
'; echo '
'; $famids = array(); $families = $controller->record->getSpouseFamilies(); foreach ($families as $family) { $famids[] = $family->getXref(); } $indifacts = array(); foreach ($controller->record->getFacts() as $fact) { $indifacts[] = $fact; } foreach ($controller->record->getSpouseFamilies() as $family) { foreach ($family->getFacts() as $fact) { $indifacts[] = $fact; } } sort_facts($indifacts); $this->buildIndividualMap($controller->record, $indifacts, $famids); echo '
'; echo '
'; // start echo ''; // end echo '
'; echo ''; return '
' . ob_get_clean() . '
'; } else { $html = ''; $html .= ''; if (Auth::isAdmin()) { $html .= ''; } return $html; } } /** {@inheritdoc} */ public function hasTabContent() { global $SEARCH_SPIDER; return !$SEARCH_SPIDER && (array_key_exists('googlemap', Module::getActiveModules()) || Auth::isAdmin()); } /** {@inheritdoc} */ public function isGrayedOut() { return false; } /** * A form to edit the module configuration. */ private function config() { $action = Filter::post('action'); $controller = new PageController; $controller ->restrictAccess(Auth::isAdmin()) ->setPageTitle(I18N::translate('Google Maps™')) ->pageHeader() ->addInlineJavascript('jQuery("#tabs").tabs();'); if ($action == 'update') { $this->setSetting('GM_MAP_TYPE', Filter::post('NEW_GM_MAP_TYPE')); $this->setSetting('GM_USE_STREETVIEW', Filter::post('NEW_GM_USE_STREETVIEW')); $this->setSetting('GM_MIN_ZOOM', Filter::post('NEW_GM_MIN_ZOOM')); $this->setSetting('GM_MAX_ZOOM', Filter::post('NEW_GM_MAX_ZOOM')); $this->setSetting('GM_XSIZE', Filter::post('NEW_GM_XSIZE')); $this->setSetting('GM_YSIZE', Filter::post('NEW_GM_YSIZE')); $this->setSetting('GM_PRECISION_0', Filter::post('NEW_GM_PRECISION_0')); $this->setSetting('GM_PRECISION_1', Filter::post('NEW_GM_PRECISION_1')); $this->setSetting('GM_PRECISION_2', Filter::post('NEW_GM_PRECISION_2')); $this->setSetting('GM_PRECISION_3', Filter::post('NEW_GM_PRECISION_3')); $this->setSetting('GM_PRECISION_4', Filter::post('NEW_GM_PRECISION_4')); $this->setSetting('GM_PRECISION_5', Filter::post('NEW_GM_PRECISION_5')); $this->setSetting('GM_COORD', Filter::post('NEW_GM_COORD')); $this->setSetting('GM_PLACE_HIERARCHY', Filter::post('NEW_GM_PLACE_HIERARCHY')); $this->setSetting('GM_PH_XSIZE', Filter::post('NEW_GM_PH_XSIZE')); $this->setSetting('GM_PH_YSIZE', Filter::post('NEW_GM_PH_YSIZE')); $this->setSetting('GM_PH_MARKER', Filter::post('NEW_GM_PH_MARKER')); $this->setSetting('GM_DISP_SHORT_PLACE', Filter::post('NEW_GM_DISP_SHORT_PLACE')); for ($i = 1; $i <= 9; $i++) { $this->setSetting('GM_PREFIX_' . $i, Filter::post('NEW_GM_PREFIX_' . $i)); $this->setSetting('GM_POSTFIX_' . $i, Filter::post('NEW_GM_POSTFIX_' . $i)); } Log::addConfigurationLog('Googlemap config updated'); } ?>
' . I18N::translate('No map data for this individual'); $html .= '
'; $html .= '' . I18N::translate('Google Maps™ preferences') . ''; $html .= '
I18N::translate('hide'), true=> I18N::translate('show')), $this->getSetting('GM_USE_STREETVIEW')); ?>
: :

     
     
     
     
     
     

getSetting('GM_PLACE_HIERARCHY')); ?>
getSetting('GM_DISP_SHORT_PLACE')); ?>

getSetting('GM_COORD')); ?>

setPageTitle(I18N::translate('Select flag')) ->pageHeader(); $stats = new Stats(WT_GEDCOM); $countries = $stats->getAllCountries(); $action = Filter::post('action'); $countrySelected = Filter::get('countrySelected', null, 'Countries'); $stateSelected = Filter::get('stateSelected', null, 'States'); $country = array(); if (is_dir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/flags')) { $rep = opendir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/flags'); while ($file = readdir($rep)) { if (stristr($file, '.png')) { $country[] = substr($file, 0, strlen($file) - 4); } } closedir($rep); sort($country); } if ($countrySelected == 'Countries') { $flags = $country; } else { $flags = array(); if (is_dir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/' . $countrySelected . '/flags')) { $rep = opendir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/' . $countrySelected . '/flags'); while ($file = readdir($rep)) { if (stristr($file, '.png')) { $flags[] = substr($file, 0, strlen($file) - 4); } } closedir($rep); sort($flags); } } $flags_s = array(); if ($stateSelected != 'States' && is_dir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/' . $countrySelected . '/flags/' . $stateSelected)) { $rep = opendir(WT_ROOT . WT_MODULES_DIR . 'googlemap/places/' . $countrySelected . '/flags/' . $stateSelected); while ($file = readdir($rep)) { if (stristr($file, '.png')) { $flags_s[] = substr($file, 0, strlen($file) - 4); } } closedir($rep); sort($flags_s); } if ($action == 'ChangeFlag' && isset($_POST['FLAGS'])) { ?>

' . $flags[$i] . '  ', $flags[$i], ''; } else { echo ''; } if ($j == 4) { echo ''; $j = 0; } $j++; } echo ''; ?>   ', $flags_s[$i], ''; } if ($j == 4) { echo ''; $j = 0; } $j++; } ?>
  ', $flags[$i], '

setPageTitle(/* I18N: %s is an individual’s name */ I18N::translate('Pedigree map of %s', $controller->getPersonName())) ->pageHeader() ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL) ->addInlineJavascript('autocomplete();'); echo ''; echo '

', $controller->getPageTitle(), '

'; // -- print the form to change the number of displayed generations ?>
'; ?>

'; ?>

treesize); $i++) { // -- check to see if we have moved to the next generation if ($i + 1 >= pow(2, $curgen)) {$curgen++; } $person = $controller->ancestors[$i]; if (!empty($person)) { $name = $person->getFullName(); if ($name == I18N::translate('Private')) $priv++; $place = $person->getBirthPlace(); if (empty($place)) { $latlongval[$i] = null; } else { $latlongval[$i] = $this->getLatitudeAndLongitudeFromPlaceLocation($person->getBirthPlace()); } if ($latlongval[$i]) { $lat[$i] = str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval[$i]->pl_lati); $lon[$i] = str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval[$i]->pl_long); if (($lat[$i] != null) && ($lon[$i] != null)) { $count++; } else { // The place is in the table but has empty values if ($name) { if ($missing) { $missing .= ', '; } $missing .= '' . $name . ''; $miscount++; } } } else { // There was no place, or not listed in the map table if ($name) { if ($missing) { $missing .= ', '; } $missing .= '' . $name . ''; $miscount++; } } } } // // echo '
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; echo '
'; if (Auth::isAdmin()) { echo ''; echo ''; echo ''; echo ''; echo '
'; echo '', I18N::translate('Google Maps™ preferences'), ''; echo ''; echo '', I18N::translate('Geographic data'), ''; echo ''; echo '', I18N::translate('Place check'), ''; echo '
'; } echo '
'; echo '
'; // display info under map echo '
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; // print summary statistics if (isset($curgen)) { $total = pow(2, $curgen) - 1; echo I18N::plural( '%1$d individual displayed, out of the normal total of %2$d, from %3$d generations.', '%1$d individuals displayed, out of the normal total of %2$d, from %3$d generations.', $count, $count, $total, $curgen ), '
'; echo '
'; if ($priv) { echo I18N::plural('%s individual is private.', '%s individuals are private.', $priv, $priv), '
'; } if ($count + $priv != $total) { if ($miscount == 0) { echo I18N::translate('No ancestors in the database.'), "
"; } else { echo /* I18N: %1$d is a count of individuals, %2$s is a list of their names */ I18N::plural( '%1$d individual is missing birthplace map coordinates: %2$s.', '%1$d individuals are missing birthplace map coordinates: %2$s.', $miscount, $miscount, $missing), '
'; } } } echo '
'; echo '
'; // close #pedigreemap_chart echo '
'; // close #pedigreemap-page ?> googleMapsScript(), '">'; $controller->addInlineJavascript($this->pedigreeMapJavascript($hideflags, $hidelines)); } /** * @param boolean $hideflags * @param boolean $hidelines * * @return string */ private function pedigreeMapJavascript($hideflags, $hidelines) { global $controller, $SHOW_HIGHLIGHT_IMAGES, $PEDIGREE_GENERATIONS; // The HomeControl returns the map to the original position and style $js = 'function HomeControl(controlDiv, pm_map) {' . // Set CSS styles for the DIV containing the control // Setting padding to 5 px will offset the control from the edge of the map 'controlDiv.style.paddingTop = "5px"; controlDiv.style.paddingRight = "0px";'. // Set CSS for the control border 'var controlUI = document.createElement("DIV"); controlUI.style.backgroundColor = "white"; controlUI.style.color = "black"; controlUI.style.borderColor = "black"; controlUI.style.borderColor = "black"; controlUI.style.borderStyle = "solid"; controlUI.style.borderWidth = "2px"; controlUI.style.cursor = "pointer"; controlUI.style.textAlign = "center"; controlUI.title = ""; controlDiv.appendChild(controlUI);'. // Set CSS for the control interior 'var controlText = document.createElement("DIV"); controlText.style.fontFamily = "Arial,sans-serif"; controlText.style.fontSize = "12px"; controlText.style.paddingLeft = "15px"; controlText.style.paddingRight = "15px"; controlText.innerHTML = "'. I18N::translate('Redraw map') . '<\/b>"; controlUI.appendChild(controlText);'. // Setup the click event listeners: simply set the map to original LatLng 'google.maps.event.addDomListener(controlUI, "click", function() { pm_map.setMapTypeId(google.maps.MapTypeId.TERRAIN), pm_map.fitBounds(bounds), pm_map.setCenter(bounds.getCenter()), infowindow.close() if (document.getElementById(lastlinkid) != null) { document.getElementById(lastlinkid).className = "person_box:target"; } }); }'. // This function picks up the click and opens the corresponding info window 'function myclick(i) { if (document.getElementById(lastlinkid) != null) { document.getElementById(lastlinkid).className = "person_box:target"; } google.maps.event.trigger(gmarkers[i], "click"); }'. // this variable will collect the html which will eventually be placed in the side_bar 'var side_bar_html = "";' . // arrays to hold copies of the markers and html used by the side_bar // because the function closure trick doesnt work there 'var gmarkers = []; var i = 0; var lastlinkid; var infowindow = new google.maps.InfoWindow({});'. // === Create an associative array of GIcons() 'var gicons = []; gicons["1"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon1.png") gicons["1"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["2"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2.png") gicons["2"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["2L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["2L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["2R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["2R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["2Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["2Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon2Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["3"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3.png") gicons["3"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["3L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["3L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["3R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["3R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["3Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["3Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon3Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["4"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4.png") gicons["4"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["4L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["4L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["4R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["4R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["4Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["4Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon4Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["5"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5.png") gicons["5"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["5L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["5L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["5R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["5R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["5Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["5Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon5Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["6"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6.png") gicons["6"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["6L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["6L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["6R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["6R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["6Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["6Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon6Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["7"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7.png") gicons["7"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["7L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["7L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["7R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["7R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["7Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["7Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon7Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor ); gicons["8"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8.png") gicons["8"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow50.png", new google.maps.Size(37, 34), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(10, 34) // Shadow anchor is base of image ); gicons["8L"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8L.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(28, 28) // Image anchor ); gicons["8L"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-left-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(32, 27) // Shadow anchor is base of image ); gicons["8R"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8R.png", new google.maps.Size(32, 32), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(4, 28) // Image anchor ); gicons["8R"].shadow = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/shadow-right-large.png", new google.maps.Size(49, 32), // Shadow size new google.maps.Point(0, 0), // Shadow origin new google.maps.Point(15, 27) // Shadow anchor is base of image ); gicons["8Ls"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8Ls.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(22, 22) // Image anchor ); gicons["8Rs"] = new google.maps.MarkerImage(WT_STATIC_URL+WT_MODULES_DIR+"googlemap/images/icon8Rs.png", new google.maps.Size(24, 24), // Image size new google.maps.Point(0, 0), // Image origin new google.maps.Point(2, 22) // Image anchor );'. // / A function to create the marker and set up the event window 'function createMarker(point, name, html, mhtml, icontype) { var contentString = "
"+mhtml+"<\/div>";'. // Create a marker with the requested icon 'var marker = new google.maps.Marker({ icon: gicons[icontype], shadow: gicons[icontype].shadow, map: pm_map, position: point, zIndex: 0 }); var linkid = "link"+i; google.maps.event.addListener(marker, "click", function() { infowindow.close(); infowindow.setContent(contentString); infowindow.open(pm_map, marker); document.getElementById(linkid).className = "person_box"; if (document.getElementById(lastlinkid) != null) { document.getElementById(lastlinkid).className = "person_box:target"; } lastlinkid=linkid; });'. // save the info we need to use later for the side_bar 'gmarkers[i] = marker;' . // add a line to the side_bar html 'side_bar_html += "
" + html +"
"; i++; return marker; };'. // create the map 'var myOptions = { zoom: 6, center: new google.maps.LatLng(0, 0), mapTypeId: google.maps.MapTypeId.TERRAIN, // ROADMAP, SATELLITE, HYBRID, TERRAIN mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU // DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR }, navigationControlOptions: { position: google.maps.ControlPosition.TOP_RIGHT, // BOTTOM, BOTTOM_LEFT, LEFT, TOP, etc style: google.maps.NavigationControlStyle.SMALL // ANDROID, DEFAULT, SMALL, ZOOM_PAN }, streetViewControl: false, // Show Pegman or not scrollwheel: true }; var pm_map = new google.maps.Map(document.getElementById("pm_map"), myOptions); google.maps.event.addListener(pm_map, "click", function() { if (document.getElementById(lastlinkid) != null) { document.getElementById(lastlinkid).className = "person_box:target"; } infowindow.close(); });'. // Create the DIV to hold the control and call HomeControl() passing in this DIV. -- 'var homeControlDiv = document.createElement("DIV"); var homeControl = new HomeControl(homeControlDiv, pm_map); homeControlDiv.index = 1; pm_map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);'. // create the map bounds 'var bounds = new google.maps.LatLngBounds();'; // add the points $curgen = 1; $count = 0; $colored_line = array( '1' => '#FF0000', '2' => '#0000FF', '3' => '#00FF00', '4' => '#FFFF00', '5' => '#00FFFF', '6' => '#FF00FF', '7' => '#C0C0FF', '8' => '#808000', ); $lat = array(); $lon = array(); $latlongval = array(); $flags = array(); for ($i = 0; $i < $controller->treesize; $i++) { // moved up to grab the sex of the individuals $person = $controller->ancestors[$i]; if ($person) { $name = $person->getFullName(); // -- check to see if we have moved to the next generation if ($i + 1 >= pow(2, $curgen)) { $curgen++; } $relationship = get_close_relationship_name($controller->root, $person); $event = ' ' . '' . $relationship . ''; // add thumbnail image if ($SHOW_HIGHLIGHT_IMAGES) { $image = $person->displayImage(); } else { $image = ''; } // end of add image $dataleft = Filter::escapeJs($image . $event . ' — ' . $name); $datamid = Filter::escapeJs(' (' . I18N::translate('View individual') . ')'); $dataright = Filter::escapeJs('
' . I18N::translate('Birth:') . ' ' . $person->getBirthDate()->display() . ' — ' . $person->getBirthPlace()); $latlongval[$i] = $this->getLatitudeAndLongitudeFromPlaceLocation($person->getBirthPlace()); if ($latlongval[$i]) { $lat[$i] = (double) str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval[$i]->pl_lati); $lon[$i] = (double) str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval[$i]->pl_long); if ($lat[$i] || $lon[$i]) { if (!$hideflags && $latlongval[$i]->pl_icon) { $flags[$i] = $latlongval[$i]->pl_icon; $ffile = strrchr($latlongval[$i]->pl_icon, '/'); $ffile = substr($ffile, 1, strpos($ffile, '.') - 1); if (empty($flags[$ffile])) { $flags[$ffile] = $i; // Only generate the flag once $js .= 'var point = new google.maps.LatLng(' . $lat[$i] . ',' . $lon[$i] . ');'; $js .= 'var Marker1_0_flag = new google.maps.MarkerImage();'; $js .= 'Marker1_0_flag.image = "' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/' . $flags[$i] . '";'; $js .= 'Marker1_0_flag.shadow = "' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/images/flag_shadow.png";'; $js .= 'Marker1_0_flag.iconSize = new google.maps.Size(25, 15);'; $js .= 'Marker1_0_flag.shadowSize = new google.maps.Size(35, 45);'; $js .= 'Marker1_0_flag.iconAnchor = new google.maps.Point(12, 15);'; $js .= 'var Marker1_0 = new google.maps.LatLng(point, {icon:Marker1_0_flag});'; } } $marker_number = $curgen; $dups = 0; for ($k = 0; $k < $i; $k++) { if ($latlongval[$i] == $latlongval[$k]) { $dups++; switch ($dups) { case 1: $marker_number = $curgen . 'L'; break; case 2: $marker_number = $curgen . 'R'; break; case 3: $marker_number = $curgen . 'Ls'; break; case 4: $marker_number = $curgen . 'Rs'; break; case 5: //adjust position where markers have same coodinates default: $marker_number = $curgen; $lon[$i] = $lon[$i] + 0.0025; $lat[$i] = $lat[$i] + 0.0025; break; } } } $js .= 'var point = new google.maps.LatLng(' . $lat[$i] . ',' . $lon[$i] . ');'; $js .= "var marker = createMarker(point, \"" . Filter::escapeJs($name) . "\",\"
" . $dataleft . $datamid . $dataright . "
\", \""; $js .= "
"; $js .= "" . $dataleft . "" . $datamid . $dataright . "
\", \"" . $marker_number . "\");"; // Construct the polygon lines if (!$hidelines) { $to_child = (intval(($i - 1) / 2)); // Draw a line from parent to child if (array_key_exists($to_child, $lat) && $lat[$to_child] != 0 && $lon[$to_child] != 0) { $js .= ' var linecolor; var plines; var lines = [new google.maps.LatLng('.$lat[$i] . ',' . $lon[$i] . '), new google.maps.LatLng('.$lat[$to_child] . ',' . $lon[$to_child] . ')]; linecolor = "'.$colored_line[$curgen] . '"; plines = new google.maps.Polygon({ paths: lines, strokeColor: linecolor, strokeOpacity: 0.8, strokeWeight: 3, fillColor: "#FF0000", fillOpacity: 0.1 }); plines.setMap(pm_map);'; } } // Extend and fit marker bounds $js .= 'bounds.extend(point);'; $js .= 'pm_map.fitBounds(bounds);'; $count++; } } } else { $latlongval[$i] = null; } } $js .= 'pm_map.setCenter(bounds.getCenter());' . // Close the sidebar highlight when the infowindow is closed 'google.maps.event.addListener(infowindow, "closeclick", function() { document.getElementById(lastlinkid).className = "person_box:target"; });'. // put the assembled side_bar_html contents into the side_bar div 'document.getElementById("side_bar").innerHTML = side_bar_html;' . // create the context menu div 'var contextmenu = document.createElement("div"); contextmenu.style.visibility="hidden"; contextmenu.innerHTML = "
  '. I18N::translate('Zoom in') . '  
" + "
  '. I18N::translate('Zoom out') . '  
" + "
  '. I18N::translate('Zoom in here') . '
" + "
  '. I18N::translate('Zoom out here') . '  
" + "
  '. I18N::translate('Center map here') . '  
";' . // listen for singlerightclick 'google.maps.event.addListener(pm_map,"singlerightclick", function(pixel,tile) {' . // store the "pixel" info in case we need it later // adjust the context menu location if near an egde // create a GControlPosition // apply it to the context menu, and make the context menu visible 'clickedPixel = pixel; var x=pixel.x; var y=pixel.y; if (x > pm_map.getSize().width - 120) { x = pm_map.getSize().width - 120 } if (y > pm_map.getSize().height - 100) { y = pm_map.getSize().height - 100 } var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x,y)); pos.apply(contextmenu); contextmenu.style.visibility = "visible"; }); '. // functions that perform the context menu options 'function zoomIn() {' . // perform the requested operation 'pm_map.zoomIn();' . // hide the context menu now that it has been used 'contextmenu.style.visibility="hidden"; } function zoomOut() {'. // perform the requested operation 'pm_map.zoomOut();' . // hide the context menu now that it has been used 'contextmenu.style.visibility="hidden"; } function zoomInHere() {'. // perform the requested operation 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel) pm_map.zoomIn(point,true);'. // hide the context menu now that it has been used 'contextmenu.style.visibility="hidden"; } function zoomOutHere() {'. // perform the requested operation 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel) pm_map.setCenter(point,pm_map.getZoom()-1);'. // There is no pm_map.zoomOut() equivalent // hide the context menu now that it has been used 'contextmenu.style.visibility="hidden"; } function centreMapHere() {'. // perform the requested operation 'var point = pm_map.fromContainerPixelToLatLng(clickedPixel) pm_map.setCenter(point);'. // hide the context menu now that it has been used 'contextmenu.style.visibility="hidden"; }'. // If the user clicks on the map, close the context menu 'google.maps.event.addListener(pm_map, "click", function() { contextmenu.style.visibility="hidden"; });'; return $js; } /** * ... */ private function adminPlaceCheck() { $action = Filter::get('action', '', 'go'); $gedcom_id = Filter::get('gedcom_id', null, WT_GED_ID); $country = Filter::get('country', '.+', 'XYZ'); $state = Filter::get('state', '.+', 'XYZ'); $matching = Filter::getBool('matching'); $controller = new PageController; $controller ->restrictAccess(Auth::isAdmin()) ->setPageTitle(I18N::translate('Google Maps™')) ->pageHeader(); echo '
', I18N::translate('Google Maps™ preferences'), ' ', I18N::translate('Geographic data'), ' ', I18N::translate('Place check'), '
'; //Start of User Defined options echo '
'; echo select_edit_control('gedcom_id', Tree::getIdList(), null, $gedcom_id, ' onchange="this.form.submit();"'); echo ' '; if ($country != 'XYZ') { echo ' '; } echo ''; echo ''; echo '
'; // close div gm_check echo ''; echo '
'; //close form placecheck echo '
'; switch ($action) { case 'go': //Identify gedcom file $trees = Tree::getAll(); echo '
', $trees[$gedcom_id]->titleHtml(), '
'; //Select all '2 PLAC ' tags in the file and create array $place_list = array(); $ged_data = Database::prepare("SELECT i_gedcom FROM `##individuals` WHERE i_gedcom LIKE ? AND i_file=?") ->execute(array("%\n2 PLAC %", $gedcom_id)) ->fetchOneColumn(); foreach ($ged_data as $ged_datum) { preg_match_all('/\n2 PLAC (.+)/', $ged_datum, $matches); foreach ($matches[1] as $match) { $place_list[$match] = true; } } $ged_data = Database::prepare("SELECT f_gedcom FROM `##families` WHERE f_gedcom LIKE ? AND f_file=?") ->execute(array("%\n2 PLAC %", $gedcom_id)) ->fetchOneColumn(); foreach ($ged_data as $ged_datum) { preg_match_all('/\n2 PLAC (.+)/', $ged_datum, $matches); foreach ($matches[1] as $match) { $place_list[$match] = true; } } // Unique list of places $place_list = array_keys($place_list); // Apply_filter if ($country == 'XYZ') { $filter = '.*$'; } else { $filter = preg_quote($country) . '$'; if ($state != 'XYZ') { $filter = preg_quote($state) . ', ' . $filter; } } $place_list = preg_grep('/' . $filter . '/', $place_list); //sort the array, limit to unique values, and count them usort($place_list, 'Webtrees\I18N::strcasecmp'); $i = count($place_list); //calculate maximum no. of levels to display $x = 0; $max = 0; while ($x < $i) { $levels = explode(",", $place_list[$x]); $parts = count($levels); if ($parts > $max) $max = $parts; $x++; } $x = 0; //scripts for edit, add and refresh ?> '; echo ''; echo ''; echo ''; echo ''; while ($cols < $max) { if ($cols == 0) { echo ''; } else { echo ''; } $cols++; } echo ''; $cols = 0; while ($cols < $max) { echo ''; $cols++; } echo ''; $countrows = 0; $matched = array(); while ($x < $i) { $placestr = ""; $levels = explode(",", $place_list[$x]); $parts = count($levels); $levels = array_reverse($levels); $placestr .= "$ppart) { $ppart = urlencode(trim($ppart)); $placestr .= "&parent[$pindex]=" . $ppart . ""; } $placestr .= "\">" . $place_list[$x] . ""; $gedplace = ""; $z = 0; $id = 0; $level = 0; $matched[$x] = 0; // used to exclude places where the gedcom place is matched at all levels $mapstr_edit = ""; $mapstr7 = "')\">"; $mapstr8 = ""; $plac = array(); $lati = array(); $long = array(); while ($z < $parts) { if ($levels[$z] == ' ' || $levels[$z] == '') $levels[$z] = "unknown"; // GoogleMap module uses "unknown" while GEDCOM uses , , $levels[$z] = rtrim(ltrim($levels[$z])); $placelist = $this->createPossiblePlaceNames($levels[$z], $z + 1); // add the necessary prefix/postfix values to the place name foreach ($placelist as $key=>$placename) { $row = Database::prepare("SELECT pl_id, pl_place, pl_long, pl_lati, pl_zoom FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ? ORDER BY pl_place") ->execute(array($z, $id, $placename)) ->fetchOneRow(PDO::FETCH_ASSOC); if (!empty($row['pl_id'])) { $row['pl_placerequested'] = $levels[$z]; // keep the actual place name that was requested so we can display that instead of what is in the db break; } } if ($row['pl_id'] != '') { $id = $row['pl_id']; } if ($row['pl_place'] != '') { $placestr2 = $mapstr_edit . $id . "&level=" . $level . $mapstr3 . $mapstr5 . I18N::translate('Zoom=') . $row['pl_zoom'] . $mapstr6 . $row['pl_placerequested'] . $mapstr8; if ($row['pl_place'] == 'unknown') $matched[$x]++; } else { if ($levels[$z] == "unknown") { $placestr2 = $mapstr_add . $id . "&level=" . $level . $mapstr3 . $mapstr7 . "" . rtrim(ltrim(I18N::translate('unknown'))) . "" . $mapstr8; $matched[$x]++; } else { $placestr2 = $mapstr_add . $id . "&place_name=" . urlencode($levels[$z]) . "&level=" . $level . $mapstr3 . $mapstr7 . '' . rtrim(ltrim($levels[$z])) . '' . $mapstr8; $matched[$x]++; } } $plac[$z] = "\n"; if ($row['pl_lati'] == '0') { $lati[$z] = ""; } elseif ($row['pl_lati'] != '') { $lati[$z] = ""; } else { $lati[$z] = ""; $matched[$x]++; } if ($row['pl_long'] == '0') { $long[$z] = ""; } elseif ($row['pl_long'] != '') { $long[$z] = ""; } else { $long[$z] = ""; $matched[$x]++; } $level++; $mapstr3 = $mapstr3 . "&parent[" . $z . "]=" . Filter::escapeJs($row['pl_placerequested']); $mapstr4 = $mapstr4 . "&parent[" . $z . "]=" . Filter::escapeJs($levels[$z]); $z++; } if ($matching) { $matched[$x] = 1; } if ($matched[$x] != 0) { echo $gedplace; $z = 0; while ($z < $max) { if ($z < $parts) { echo $plac[$z]; echo $lati[$z]; echo $long[$z]; } else { echo ''; } $z++; } echo ''; $countrows++; } $x++; } // echo final row of table echo '
', I18N::translate('Place'), '', I18N::translate('Geographic data'), '
', I18N::translate('Country'), '', I18N::translate('Level'), ' ', $cols + 1, '
', WT_Gedcom_Tag::getLabel('PLAC'), '', I18N::translate('Latitude'), '', I18N::translate('Longitude'), '
" . $placestr . "" . $placestr2 . "" . $row['pl_lati'] . "" . $row['pl_lati'] . "X" . $row['pl_long'] . "" . $row['pl_long'] . "X
', /* I18N: A count of places */ I18N::translate('Total places: %s', I18N::number($countrows)), '
'; break; default: // Do not run until user selects a gedcom/place/etc. // Instead, show some useful help info. echo '
', I18N::translate('This will list all the places from the selected GEDCOM file. By default this will NOT INCLUDE places that are fully matched between the GEDCOM file and the GoogleMap tables'), '
'; break; } } /** * @return string */ private function checkMapData() { global $controller; $xrefs = "'" . $controller->record->getXref() . "'"; $families = $controller->record->getSpouseFamilies(); foreach ($families as $family) { $xrefs .= ", '" . $family->getXref() . "'"; } return Database::prepare( "SELECT COUNT(*) AS tot FROM `##placelinks` WHERE pl_gid IN (" . $xrefs . ") AND pl_file=?" )->execute(array(WT_GED_ID))->fetchOne(); } /** * @param string $prefix_list * @param string $place * @param string[] $placelist * * @return string[] */ private function removePrefixFromPlaceName($prefix_list, $place, $placelist) { if ($prefix_list) { foreach (explode(';', $prefix_list) as $prefix) { if ($prefix && substr($place, 0, strlen($prefix) + 1) == $prefix . ' ') { $placelist[] = substr($place, strlen($prefix) + 1); } } } return $placelist; } /** * @param string $suffix_list * @param string $place * @param string[] $placelist * * @return string[] */ private function removeSuffixFromPlaceName($suffix_list, $place, $placelist) { if ($suffix_list) { foreach (explode(';', $suffix_list) as $postfix) { if ($postfix && substr($place, -strlen($postfix) - 1) == ' ' . $postfix) { $placelist[] = substr($place, 0, strlen($place) - strlen($postfix) - 1); } } } return $placelist; } /** * @param string $prefix_list * @param string $suffix_list * @param string $place * @param string[] $placelist * * @return string[] */ private function removePrefixAndSuffixFromPlaceName($prefix_list, $suffix_list, $place, $placelist) { if ($prefix_list && $suffix_list) { foreach (explode(';', $prefix_list) as $prefix) { foreach (explode(';', $suffix_list) as $postfix) { if ($prefix && $postfix && substr($place, 0, strlen($prefix) + 1) == $prefix . ' ' && substr($place, -strlen($postfix) - 1) == ' ' . $postfix) { $placelist[] = substr($place, strlen($prefix) + 1, strlen($place) - strlen($prefix) - strlen($postfix) - 2); } } } } return $placelist; } /** * @param string $placename * @param integer $level * * @return string[] */ private function createPossiblePlaceNames($placename, $level) { $retlist = array(); if ($level <= 9) { $retlist = $this->removePrefixAndSuffixFromPlaceName($this->getSetting('GM_PREFIX_' . $level), $this->getSetting('GM_POSTFIX_' . $level), $placename, $retlist); // Remove both $retlist = $this->removePrefixFromPlaceName($this->getSetting('GM_PREFIX_' . $level), $placename, $retlist); // Remove prefix $retlist = $this->removeSuffixFromPlaceName($this->getSetting('GM_POSTFIX_' . $level), $placename, $retlist); // Remove suffix } $retlist[] = $placename; // Exact return $retlist; } /** * @param string $place * * @return null|stdClass */ private function getLatitudeAndLongitudeFromPlaceLocation($place) { $parent = explode(',', $place); $parent = array_reverse($parent); $place_id = 0; for ($i = 0; $i < count($parent); $i++) { $parent[$i] = trim($parent[$i]); if (empty($parent[$i])) { $parent[$i] = 'unknown'; // GoogleMap module uses "unknown" while GEDCOM uses , , } $placelist = $this->createPossiblePlaceNames($parent[$i], $i + 1); foreach ($placelist as $placename) { $pl_id = Database::prepare( "SELECT pl_id FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ? ORDER BY pl_place" )->execute(array($i, $place_id, $placename))->fetchOne(); if (!empty($pl_id)) { break; } } if (empty($pl_id)) { break; } $place_id = $pl_id; } return Database::prepare( "SELECT sv_lati, sv_long, sv_bearing, sv_elevation, sv_zoom, pl_lati, pl_long, pl_zoom, pl_icon, pl_level" . " FROM `##placelocation`" . " WHERE pl_id = ?" . " ORDER BY pl_place" )->execute(array($place_id))->fetchOneRow(); } /** * @param Individual $indi * @param Fact[] $indifacts * @param string[] $famids */ private function buildIndividualMap(Individual $indi, $indifacts, $famids) { $GM_MAX_ZOOM = $this->getSetting('GM_MAX_ZOOM'); // Create the markers list array $gmarks = array(); sort_facts($indifacts); $i = 0; foreach ($indifacts as $fact) { if (!$fact->getPlace()->isEmpty()) { $ctla = preg_match("/\d LATI (.*)/", $fact->getGedcom(), $match1); $ctlo = preg_match("/\d LONG (.*)/", $fact->getGedcom(), $match2); if ($fact->getParent() instanceof Family) { $spouse = $fact->getParent()->getSpouse($indi); } else { $spouse = null; } if ($ctla && $ctlo) { $i++; $gmarks[$i] = array( 'class' => 'optionbox', 'date' => $fact->getDate()->display(true), 'fact_label' => $fact->getLabel(), 'image' => $spouse ? $spouse->displayImage() : Theme::theme()->icon($fact), 'info' => $fact->getValue(), 'lat' => str_replace(array('N', 'S', ','), array('', '-', '.'), $match1[1]), 'lng' => str_replace(array('E', 'W', ','), array('', '-', '.'), $match2[1]), 'name' => $spouse ? 'getFullName() . '' : '', 'pl_icon' => '', 'place' => $fact->getPlace()->getFullName(), 'sv_bearing' => '0', 'sv_elevation' => '0', 'sv_lati' => '0', 'sv_long' => '0', 'sv_zoom' => '0', 'tooltip' => $fact->getPlace()->getGedcomName(), ); } else { $latlongval = $this->getLatitudeAndLongitudeFromPlaceLocation($fact->getPlace()->getGedcomName()); if ($latlongval && $latlongval->pl_lati && $latlongval->pl_long) { $i++; $gmarks[$i] = array( 'class' => 'optionbox', 'date' => $fact->getDate()->display(true), 'fact_label' => $fact->getLabel(), 'image' => $spouse ? $spouse->displayImage() : Theme::theme()->icon($fact), 'info' => $fact->getValue(), 'lat' => str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval->pl_lati), 'lng' => str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval->pl_long), 'name' => $spouse ? 'getFullName() . '' : '', 'pl_icon' => $latlongval->pl_icon, 'place' => $fact->getPlace()->getFullName(), 'sv_bearing' => $latlongval->sv_bearing, 'sv_elevation' => $latlongval->sv_elevation, 'sv_lati' => $latlongval->sv_lati, 'sv_long' => $latlongval->sv_long, 'sv_zoom' => $latlongval->sv_zoom, 'tooltip' => $fact->getPlace()->getGedcomName(), ); if ($GM_MAX_ZOOM > $latlongval->pl_zoom) { $GM_MAX_ZOOM = $latlongval->pl_zoom; } } } } } // Add children to the markers list array foreach ($famids as $xref) { $family = Family::getInstance($xref); foreach ($family->getChildren() as $child) { $birth = $child->getFirstFact('BIRT'); if ($birth) { $birthrec = $birth->getGedcom(); if (!$birth->getPlace()->isEmpty()) { $ctla = preg_match('/\n4 LATI (.+)/', $birthrec, $match1); $ctlo = preg_match('/\n4 LONG (.+)/', $birthrec, $match2); if ($ctla && $ctlo) { $i++; $gmarks[$i] = array( 'date' => $birth->getDate()->display(true), 'image' => $child->displayImage(), 'info' => '', 'lat' => str_replace(array('N', 'S', ','), array('', '-', '.'), $match1[1]), 'lng' => str_replace(array('E', 'W', ','), array('', '-', '.'), $match2[1]), 'name' => 'getFullName() . '', 'pl_icon' => '', 'place' => $birth->getPlace()->getFullName(), 'sv_bearing' => '0', 'sv_elevation' => '0', 'sv_lati' => '0', 'sv_long' => '0', 'sv_zoom' => '0', 'tooltip' => $birth->getPlace()->getGedcomName(), ); switch ($child->getSex()) { case'F': $gmarks[$i]['fact_label'] = I18N::translate('daughter'); $gmarks[$i]['class'] = 'person_boxF'; break; case 'M': $gmarks[$i]['fact_label'] = I18N::translate('son'); $gmarks[$i]['class'] = 'person_box'; break; default: $gmarks[$i]['fact_label'] = I18N::translate('child'); $gmarks[$i]['class'] = 'person_boxNN'; break; } } else { $latlongval = $this->getLatitudeAndLongitudeFromPlaceLocation($birth->getPlace()->getGedcomName()); if ($latlongval && $latlongval->pl_lati && $latlongval->pl_long) { $i++; $gmarks[$i] = array( 'date' => $birth->getDate()->display(true), 'image' => $child->displayImage(), 'info' => '', 'lat' => str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval->pl_lati), 'lng' => str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval->pl_long), 'name' => 'getFullName() . '', 'pl_icon' => $latlongval->pl_icon, 'place' => $birth->getPlace()->getFullName(), 'sv_bearing' => $latlongval->sv_bearing, 'sv_elevation' => $latlongval->sv_elevation, 'sv_lati' => $latlongval->sv_lati, 'sv_long' => $latlongval->sv_long, 'sv_zoom' => $latlongval->sv_zoom, 'tooltip' => $birth->getPlace()->getGedcomName(), ); switch ($child->getSex()) { case 'M': $gmarks[$i]['fact_label'] = I18N::translate('son'); $gmarks[$i]['class'] = 'person_box'; break; case 'F': $gmarks[$i]['fact_label'] = I18N::translate('daughter'); $gmarks[$i]['class'] = 'person_boxF'; break; default: $gmarks[$i]['fact_label'] = I18N::translate('child'); $gmarks[$i]['class'] = 'option_boxNN'; break; } if ($GM_MAX_ZOOM > $latlongval->pl_zoom) { $GM_MAX_ZOOM = $latlongval->pl_zoom; } } } } } } } // Group markers by location $location_groups = array(); foreach ($gmarks as $gmark) { $key = $gmark['lat'] . $gmark['lng']; if (isset($location_groups[$key])) { $location_groups[$key][] = $gmark; } else { $location_groups[$key] = array($gmark); } } $location_groups = array_values($location_groups); // *** ENABLE STREETVIEW *** $STREETVIEW = $this->getSetting('GM_USE_STREETVIEW'); ?> getSetting('GM_YSIZE'), 'px;">'; foreach ($location_groups as $key=>$location_group) { foreach ($location_group as $gmark) { echo ''; echo ''; echo ''; echo ''; } } echo '
'; echo '', $gmark['fact_label'], ''; if ($gmark['info']) { echo '', Filter::escapeHtml($gmark['info']), '
'; } if ($gmark['name']) { echo $gmark['name'], '
'; } echo $gmark['place'], '
'; if ($gmark['date']) { echo $gmark['date'], '
'; } echo '

'; } /** * @param string $place * * @return integer */ private function getPlaceLocationId($place) { $par = explode(',', strip_tags($place)); $par = array_reverse($par); $place_id = 0; $pl_id = 0; for ($i = 0; $i < count($par); $i++) { $par[$i] = trim($par[$i]); if (empty($par[$i])) { $par[$i] = 'unknown'; } $placelist = $this->createPossiblePlaceNames($par[$i], $i + 1); foreach ($placelist as $key => $placename) { $pl_id = (int) Database::prepare( "SELECT pl_id FROM `##placelocation` WHERE pl_level = :level AND pl_parent_id = :parent_id AND pl_place LIKE :placename" )->execute(array( 'level' => $i, 'parent_id' => $place_id, 'placename' => $placename, ))->fetchOne(); if ($pl_id) { break; } } if (!$pl_id) { break; } $place_id = $pl_id; } return $place_id; } /** * @param string $place * * @return integer */ private function getPlaceId($place) { $par = explode(',', $place); $par = array_reverse($par); $place_id = 0; $pl_id = 0; for ($i = 0; $i < count($par); $i++) { $par[$i] = trim($par[$i]); $placelist = $this->createPossiblePlaceNames($par[$i], $i + 1); foreach ($placelist as $placename) { $pl_id = (int) Database::prepare( "SELECT p_id FROM `##places` WHERE p_parent_id = :place_id AND p_file = :tree_id AND p_place = :placename" )->execute(array( 'place_id' => $place_id, 'tree_id' => WT_GED_ID, 'placename' => $placename, ))->fetchOne(); if ($pl_id) { break; } } if (!$pl_id) { break; } $place_id = $pl_id; } return $place_id; } /** * @param integer $level * @param string[] $parent * * @return integer */ private function setPlaceIdMap($level, $parent) { $fullplace = ''; if ($level == 0) { return 0; } else { for ($i = 1; $i <= $level; $i++) { $fullplace .= $parent[$level - $i] . ', '; } $fullplace = substr($fullplace, 0, -2); return $this->getPlaceId($fullplace); } } /** * @param integer $level * @param string[] $parent * * @return integer */ private function setLevelMap($level, $parent) { $fullplace = ''; if ($level == 0) { return 0; } else { for ($i = 1; $i <= $level; $i++) { if ($parent[$level - $i] != '') { $fullplace .= $parent[$level - $i] . ', '; } else { $fullplace .= 'Unknown, '; } } $fullplace = substr($fullplace, 0, -2); return $this->getPlaceLocationId($fullplace); } } /** * Called by placelist.php * * @param string $placelevels */ public function createMap($placelevels) { global $level, $levelm, $plzoom, $controller; $STREETVIEW = $this->getSetting('GM_USE_STREETVIEW'); $parent = Filter::getArray('parent'); // create the map echo ''; echo ''; } // End Streetview window =================================================================== } /** * @param integer $numls * @param integer $levelm * * @return integer[] */ private function checkWhereAmI($numls, $levelm) { $where_am_i = $this->placeIdToHierarchy($levelm); $i = $numls + 1; $levelo = array(0 => 0); foreach (array_reverse($where_am_i, true) as $id => $place2) { $levelo[$i] = $id; $i--; } return $levelo; } /** * @param integer $level * @param string[] $parent */ private function printHowManyPeople($level, $parent) { $stats = new Stats(WT_GEDCOM); $place_count_indi = 0; $place_count_fam = 0; if (!isset($parent[$level - 1])) { $parent[$level - 1] = ''; } $p_id = $this->setPlaceIdMap($level, $parent); $indi = $stats->statsPlaces('INDI', false, $p_id); $fam = $stats->statsPlaces('FAM', false, $p_id); foreach ($indi as $place) { $place_count_indi = $place['tot']; } foreach ($fam as $place) { $place_count_fam = $place['tot']; } echo '

', I18N::translate('Individuals'), ': ', $place_count_indi, ', ', I18N::translate('Families'), ': ', $place_count_fam; } /** * @param string[] $place2 * @param integer $level * @param string[] $parent * @param integer $levelm * @param string $linklevels * @param string $placelevels * @param boolean $lastlevel */ private function printGoogleMapMarkers($place2, $level, $parent, $levelm, $linklevels, $placelevels, $lastlevel = false) { if (($place2['lati'] == null) || ($place2['long'] == null) || (($place2['lati'] == '0') && ($place2['long'] == '0'))) { echo 'var icon_type = new google.maps.MarkerImage();'; echo 'icon_type.image = "', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/marker_yellow.png";'; echo 'icon_type.shadow = "', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/shadow50.png";'; echo 'icon_type.iconSize = google.maps.Size(20, 34);'; echo 'icon_type.shadowSize = google.maps.Size(37, 34);'; echo 'var point = new google.maps.LatLng(0, 0);'; if ($lastlevel) echo "var marker = createMarker(point, \"

"; else { echo "var marker = createMarker(point, \"
\", icon_type, \"", str_replace(array('‎', '‏'), array(WT_UTF8_LRM, WT_UTF8_RLM), addslashes($place2['place'])), "\");\n"; } else { $lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $place2['lati']); $long = str_replace(array('E', 'W', ','), array('', '-', '.'), $place2['long']); //delete leading zero if ($lati >= 0) { $lati = abs($lati); } elseif ($lati < 0) { $lati = '-' . abs($lati); } if ($long >= 0) { $long = abs($long); } elseif ($long < 0) { $long = '-' . abs($long); } echo 'var icon_type = new google.maps.MarkerImage();'; if ($place2['icon'] !== null && $place2['icon'] !== '' && $this->getSetting('GM_PH_MARKER') === 'G_FLAG') { echo ' icon_type.image = "', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/', $place2['icon'], '";'; echo ' icon_type.shadow = "', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/flag_shadow.png";'; echo ' icon_type.iconSize = new google.maps.Size(25, 15);'; echo ' icon_type.shadowSize = new google.maps.Size(35, 45);'; } echo 'var point = new google.maps.LatLng(', $lati, ', ', $long, ');'; echo 'var marker = createMarker(point, "", icon_type, "', Filter::escapeJs($place2['place']), '");'; } } /** * Called by placelist.php * * @param integer $numfound * @param integer $level * @param string[] $parent * @param string $linklevels * @param string $placelevels * @param string[] $place_names */ public function mapScripts($numfound, $level, $parent, $linklevels, $placelevels, $place_names) { global $plzoom, $controller; $controller->addInlineJavascript(' jQuery("head").append(\'\'); var numMarkers = "' . $numfound . '"; var mapLevel = "' . $level . '"; var placezoom = "' . $plzoom . '"; var infowindow = new google.maps.InfoWindow({ // size: new google.maps.Size(150,50), // maxWidth: 600 }); var map_center = new google.maps.LatLng(0,0); var map = ""; var bounds = new google.maps.LatLngBounds (); var markers = []; var gmarkers = []; var i = 0; // Create the map and mapOptions var mapOptions = { zoom: 8, center: map_center, mapTypeId: google.maps.MapTypeId.' . $this->getSetting('GM_MAP_TYPE') . ', mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU // DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR }, navigationControl: true, navigationControlOptions: { position: google.maps.ControlPosition.TOP_RIGHT, // BOTTOM, BOTTOM_LEFT, LEFT, TOP, etc style: google.maps.NavigationControlStyle.SMALL // ANDROID, DEFAULT, SMALL, ZOOM_PAN }, streetViewControl: false, // Show Pegman or not scrollwheel: false }; map = new google.maps.Map(document.getElementById("place_map"), mapOptions); // Close any infowindow when map is clicked google.maps.event.addListener(map, "click", function() { infowindow.close(); }); // If only one marker, set zoom level to that of place in database if (mapLevel != 0) { var pointZoom = placezoom; } else { var pointZoom = 1; } // Creates a marker whose info window displays the given name function createMarker(point, html, icon, name) { // Choose icon and shadow ============ if (icon.image && '.$level . '<=3) { if (icon.image!="'.WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/images/marker_yellow.png") { var iconImage = new google.maps.MarkerImage(icon.image, new google.maps.Size(25, 15), new google.maps.Point(0,0), new google.maps.Point(12, 15)); var iconShadow = new google.maps.MarkerImage("'.WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/images/flag_shadow.png", new google.maps.Size(35, 45), new google.maps.Point(0,0), new google.maps.Point(1, 45)); } else { var iconImage = new google.maps.MarkerImage(icon.image, new google.maps.Size(20, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34)); var iconShadow = new google.maps.MarkerImage("https://www.google.com/mapfiles/shadow50.png", new google.maps.Size(37, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34)); } // *** Clickable area of icon - To be refined later *** =================================== // var iconShape = { // coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0], // type: "poly" // }; } else { var iconImage = new google.maps.MarkerImage("https://maps.google.com/mapfiles/marker.png", new google.maps.Size(20, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34)); var iconShadow = new google.maps.MarkerImage("https://www.google.com/mapfiles/shadow50.png", new google.maps.Size(37, 34), new google.maps.Point(0,0), new google.maps.Point(9, 34)); // *** Clickable area of icon - To be refined later *** =================================== // var iconShape = { // coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0], // type: "poly" // }; } var posn = new google.maps.LatLng(0,0); var marker = new google.maps.Marker({ position: point, icon: iconImage, shadow: iconShadow, map: map, title: name }); // Show this markers name in the info window when it is clicked google.maps.event.addListener(marker, "click", function() { infowindow.close(); infowindow.setContent(html); infowindow.open(map, marker); }); // === Store the tab, category and event info as marker properties === marker.mypoint = point; marker.mytitle = name; marker.myposn = posn; gmarkers.push(marker); bounds.extend(marker.position); // If only one marker use database place zoom level rather than fitBounds of markers if (numMarkers > 1) { map.fitBounds(bounds); } else { map.setCenter(bounds.getCenter()); map.setZoom(parseFloat(pointZoom)); } return marker; } '); $levelm = $this->setLevelMap($level, $parent); if (isset($levelo[0])) $levelo[0] = 0; $numls = count($parent) - 1; $levelo = $this->checkWhereAmI($numls, $levelm); if ($numfound < 2 && ($level == 1 || !isset($levelo[$level - 1]))) { $controller->addInlineJavascript('map.maxZoom=6;'); } elseif ($numfound < 2 && !isset($levelo[$level - 2])) { } elseif ($level == 2) { $controller->addInlineJavascript('map.maxZoom=10;'); } //create markers ob_start(); // TODO: rewrite print_gm_markers, and the functions called therein, to either return text or add JS directly. if ($numfound == 0 && $level > 0) { if (isset($levelo[($level - 1)])) { // ** BH not sure yet what this if statement is for ... TODO ** // show the current place on the map $place = Database::prepare("SELECT pl_id as place_id, pl_place as place, pl_lati as lati, pl_long as `long`, pl_zoom as zoom, pl_icon as icon FROM `##placelocation` WHERE pl_id=?") ->execute(array($levelm)) ->fetch(PDO::FETCH_ASSOC); if ($place) { // re-calculate the hierarchy information required to display the current place $thisloc = $parent; array_pop($thisloc); $thislevel = $level - 1; $thislinklevels = substr($linklevels, 0, strrpos($linklevels, '&')); if (strpos($placelevels, ',', 1)) { $thisplacelevels = substr($placelevels, strpos($placelevels, ',', 1)); } else { // this is the top level, remove everything $thisplacelevels = ''; } $this->printGoogleMapMarkers($place, $thislevel, $thisloc, $place['place_id'], $thislinklevels, $thisplacelevels); } } } // display any sub-places $placeidlist = array(); foreach ($place_names as $placename) { $thisloc = $parent; $thisloc[] = $placename; $this_levelm = $this->setLevelMap($level + 1, $thisloc); if ($this_levelm) $placeidlist[] = $this_levelm; } if ($placeidlist) { // flip the array (thus removing duplicates) $placeidlist = array_flip($placeidlist); // remove entry for parent location unset($placeidlist[$levelm]); } if ($placeidlist) { // the keys are all we care about (this reverses the earlier array_flip, and ensures there are no "holes" in the array) $placeidlist = array_keys($placeidlist); // note: this implode/array_fill code generates one '?' for each entry in the $placeidlist array $placelist = Database::prepare( "SELECT pl_id as place_id, pl_place as place, pl_lati as lati, pl_long as `long`, pl_zoom as zoom, pl_icon as icon" . " FROM `##placelocation` WHERE pl_id IN (" . implode(',', array_fill(0, count($placeidlist), '?')) . ')' )->execute($placeidlist) ->fetchAll(PDO::FETCH_ASSOC); foreach ($placelist as $place) { $this->printGoogleMapMarkers($place, $level, $parent, $place['place_id'], $linklevels, $placelevels); } } $controller->addInlineJavascript(ob_get_clean()); } /** * Take a place id and find its place in the hierarchy * Input: place ID * Output: ordered array of id=>name values, starting with the Top level * e.g. 0=>"Top level", 16=>"England", 19=>"London", 217=>"Westminster" * NB This function exists in both places.php and places_edit.php * * @param integer $id * * @return string[] */ private function placeIdToHierarchy($id) { $statement = Database::prepare("SELECT pl_parent_id, pl_place FROM `##placelocation` WHERE pl_id=?"); $arr = array(); while ($id != 0) { $row = $statement->execute(array($id))->fetchOneRow(); $arr = array($id => $row->pl_place) + $arr; $id = $row->pl_parent_id; } return $arr; } /** * @return int */ private function getHighestIndex() { return (int) Database::prepare("SELECT MAX(pl_id) FROM `##placelocation`")->fetchOne(); } /** * @return int */ private function getHighestLevel() { return (int) Database::prepare("SELECT MAX(pl_level) FROM `##placelocation`")->fetchOne(); } /** * Find all of the places in the hierarchy * * @param integer $parent_id * @param boolean $inactive * * @return array[] */ private function getPlaceListLocation($parent_id, $inactive = false) { if ($inactive) { $rows = Database::prepare( "SELECT pl_id, pl_place, pl_lati, pl_long, pl_zoom, pl_icon" . " FROM `##placelocation`" . " WHERE pl_parent_id = :parent_id" . " ORDER BY pl_place COLLATE :collation" )->execute(array( 'parent_id' => $parent_id, 'collation' => I18N::$collation, ))->fetchAll(); } else { $rows = Database::prepare( "SELECT DISTINCT pl_id, pl_place, pl_lati, pl_long, pl_zoom, pl_icon" . " FROM `##placelocation`" . " INNER JOIN `##places` ON `##placelocation`.pl_place=`##places`.p_place" . " WHERE pl_parent_id = :parent_id" . " ORDER BY pl_place COLLATE :collation" )->execute(array( 'parent_id' => $parent_id, 'collation' => I18N::$collation, ))->fetchAll(); } $placelist = array(); foreach ($rows as $row) { $placelist[] = array( 'place_id' => $row->pl_id, 'place' => $row->pl_place, 'lati' => $row->pl_lati, 'long' => $row->pl_long, 'zoom' => $row->pl_zoom, 'icon' => $row->pl_icon, ); } return $placelist; } /** * @param integer $parent_id */ private function outputLevel($parent_id) { $tmp = $this->placeIdToHierarchy($parent_id); $maxLevel = $this->getHighestLevel(); if ($maxLevel > 8) { $maxLevel = 8; } $prefix = implode(';', $tmp); if ($prefix != '') { $prefix .= ';'; } $suffix = str_repeat(';', $maxLevel - count($tmp)); $level = count($tmp); $rows = Database::prepare( "SELECT pl_id, pl_place, pl_long, pl_lati, pl_zoom, pl_icon FROM `##placelocation` WHERE pl_parent_id=? ORDER BY pl_place" )->execute(array($parent_id))->fetchAll(); foreach ($rows as $row) { echo $level, ';', $prefix, $row->pl_place, $suffix, ';', $row->pl_long, ';', $row->pl_lati, ';', $row->pl_zoom, ';', $row->pl_icon, "\r\n"; if ($level < $maxLevel) { $this->outputLevel($row->pl_id); } } } /** * recursively find all of the csv files on the server * * @param string $path * * @return string[] */ private function findFiles($path) { $placefiles = array(); if (file_exists($path)) { $dir = dir($path); while (false !== ($entry = $dir->read())) { if ($entry !== '.' && $entry !== '..') { if (is_dir($path . '/' . $entry)) { $this->findFiles($path . '/' . $entry); } elseif (strstr($entry, '.csv') !== false) { $placefiles[] = preg_replace('~' . WT_MODULES_DIR . 'googlemap/extra~', '', $path) . '/' . $entry; } } } $dir->close(); } return $placefiles; } /** * ... */ private function placesEdit() { $GM_MAX_ZOOM = $this->getSetting('GM_MAX_ZOOM'); $action = Filter::post('action', null, Filter::get('action')); $placeid = Filter::post('placeid', null, Filter::get('placeid')); $place_name = Filter::post('place_name', null, Filter::get('place_name')); $controller = new SimpleController; $controller ->restrictAccess(Auth::isAdmin()) ->setPageTitle(I18N::translate('Geographic data')) ->addInlineJavascript('$("", {rel: "stylesheet", type: "text/css", href: "' . WT_STATIC_URL . WT_MODULES_DIR . 'googlemap/css/wt_v3_googlemap.css"}).appendTo("head");') ->pageHeader(); $where_am_i = $this->placeIdToHierarchy($placeid); $level = count($where_am_i); if ($action == 'addrecord' && Auth::isAdmin()) { $statement = Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); if (($_POST['LONG_CONTROL'] == '') || ($_POST['NEW_PLACE_LONG'] == '') || ($_POST['NEW_PLACE_LATI'] == '')) { $statement->execute(array($this->getHighestIndex() + 1, $placeid, $level, $_POST['NEW_PLACE_NAME'], null, null, $_POST['NEW_ZOOM_FACTOR'], $_POST['icon'])); } else { $statement->execute(array($this->getHighestIndex() + 1, $placeid, $level, $_POST['NEW_PLACE_NAME'], $_POST['LONG_CONTROL'][3] . $_POST['NEW_PLACE_LONG'], $_POST['LATI_CONTROL'][3] . $_POST['NEW_PLACE_LATI'], $_POST['NEW_ZOOM_FACTOR'], $_POST['icon'])); } // autoclose window when update successful unless debug on if (!WT_DEBUG) { $controller->addInlineJavaScript('closePopupAndReloadParent();'); } echo "
"; exit; } if ($action == 'updaterecord' && Auth::isAdmin()) { $statement = Database::prepare("UPDATE `##placelocation` SET pl_place=?, pl_lati=?, pl_long=?, pl_zoom=?, pl_icon=? WHERE pl_id=?"); if (($_POST['LONG_CONTROL'] == '') || ($_POST['NEW_PLACE_LONG'] == '') || ($_POST['NEW_PLACE_LATI'] == '')) { $statement->execute(array($_POST['NEW_PLACE_NAME'], null, null, $_POST['NEW_ZOOM_FACTOR'], $_POST['icon'], $placeid)); } else { $statement->execute(array($_POST['NEW_PLACE_NAME'], $_POST['LATI_CONTROL'][3] . $_POST['NEW_PLACE_LATI'], $_POST['LONG_CONTROL'][3] . $_POST['NEW_PLACE_LONG'], $_POST['NEW_ZOOM_FACTOR'], $_POST['icon'], $placeid)); } // autoclose window when update successful unless debug on if (!WT_DEBUG) { $controller->addInlineJavaScript('closePopupAndReloadParent();'); } echo "
"; exit; } // Update placelocation STREETVIEW fields // TODO: This ought to be a POST request, rather than a GET request if ($action == 'update_sv_params' && Auth::isAdmin()) { Database::prepare( "UPDATE `##placelocation` SET sv_lati=?, sv_long=?, sv_bearing=?, sv_elevation=?, sv_zoom=? WHERE pl_id=?" )->execute(array( Filter::get('svlati'), Filter::get('svlong'), Filter::get('svbear'), Filter::get('svelev'), Filter::get('svzoom'), $placeid )); $controller->addInlineJavaScript('window.close();'); exit; } if ($action == "update") { // --- find the place in the file $row = Database::prepare("SELECT pl_place, pl_lati, pl_long, pl_icon, pl_parent_id, pl_level, pl_zoom FROM `##placelocation` WHERE pl_id=?") ->execute(array($placeid)) ->fetchOneRow(); $place_name = $row->pl_place; $place_icon = $row->pl_icon; $selected_country = explode("/", $place_icon); if (isset($selected_country[1]) && $selected_country[1] != "flags") $selected_country = $selected_country[1]; else $selected_country = "Countries"; $parent_id = $row->pl_parent_id; $level = $row->pl_level; $zoomfactor = $row->pl_zoom; $parent_lati = "0.0"; $parent_long = "0.0"; if ($row->pl_lati !== null && $row->pl_long !== null) { $place_lati = (float) (str_replace(array('N', 'S', ','), array('', '-', '.'), $row->pl_lati)); $place_long = (float) (str_replace(array('E', 'W', ','), array('', '-', '.'), $row->pl_long)); } else { $place_lati = null; $place_long = null; $zoomfactor = 1; } do { $row = Database::prepare("SELECT pl_lati, pl_long, pl_parent_id, pl_zoom FROM `##placelocation` WHERE pl_id=?") ->execute(array($parent_id)) ->fetchOneRow(); if (!$row) { break; } if ($row->pl_lati !== null && $row->pl_long !== null) { $parent_lati = (float) (str_replace(array('N', 'S', ','), array('', '-', '.'), $row->pl_lati)); $parent_long = (float) (str_replace(array('E', 'W', ','), array('', '-', '.'), $row->pl_long)); if ($zoomfactor == 1) { $zoomfactor = $row->pl_zoom; } } $parent_id = $row->pl_parent_id; } while ($row->pl_parent_id != 0 && $row->pl_lati === null && $row->pl_long === null); echo '', Filter::escapeHtml(str_replace('Unknown', I18N::translate('unknown'), implode(I18N::$list_separator, array_reverse($where_am_i, true)))), '
'; } if ($action == 'add') { // --- find the parent place in the file if ($placeid != 0) { if (!isset($place_name)) $place_name = ''; $place_lati = null; $place_long = null; $zoomfactor = 1; $parent_lati = '0.0'; $parent_long = '0.0'; $place_icon = ''; $parent_id = $placeid; do { $row = Database::prepare("SELECT pl_lati, pl_long, pl_parent_id, pl_zoom, pl_level FROM `##placelocation` WHERE pl_id=?") ->execute(array($parent_id)) ->fetchOneRow(); if ($row->pl_lati !== null && $row->pl_long !== null) { $parent_lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $row->pl_lati); $parent_long = str_replace(array('E', 'W', ','), array('', '-', '.'), $row->pl_long); $zoomfactor = $row->pl_zoom; if ($zoomfactor > $GM_MAX_ZOOM) { $zoomfactor = $GM_MAX_ZOOM; } $level = $row->pl_level + 1; } $parent_id = $row->pl_parent_id; } while ($row->pl_parent_id != 0 && $row->pl_lati === null && $row->pl_long === null); } else { if (!isset($place_name)) $place_name = ''; $place_lati = null; $place_long = null; $parent_lati = "0.0"; $parent_long = "0.0"; $place_icon = ''; $parent_id = 0; $level = 0; $zoomfactor = $this->getSetting('GM_MIN_ZOOM'); } $selected_country = 'Countries'; if (!isset($place_name) || $place_name == "") echo '', I18N::translate('unknown'); else echo '', $place_name; if (count($where_am_i) > 0) echo ', ', Filter::escapeHtml(str_replace('Unknown', I18N::translate('unknown'), implode(I18N::$list_separator, array_reverse($where_am_i, true)))), '
'; echo '

'; } ?>
'; // echo ''; echo ''; echo ''; $plzoom = $latlng['pl_zoom']; // Map zoom level if (Auth::isAdmin()) { $placecheck_url = 'module.php?mod=googlemap&mod_action=admin_placecheck'; if ($parent && isset($parent[0])) { $placecheck_url .= '&country=' . $parent[0]; if (isset($parent[1])) { $placecheck_url .= '&state=' . $parent[1]; } } $adminplaces_url = 'module.php?mod=googlemap&mod_action=admin_places'; if ($latlng && isset($latlng['pl_id'])) { $adminplaces_url .= '&parent=' . $latlng['pl_id']; } echo '
'; $levelm = $this->setLevelMap($level, $parent); $latlng = Database::prepare("SELECT pl_place, pl_id, pl_lati, pl_long, pl_zoom, sv_long, sv_lati, sv_bearing, sv_elevation, sv_zoom FROM `##placelocation` WHERE pl_id=?") ->execute(array($levelm)) ->fetch(PDO::FETCH_ASSOC); if ($STREETVIEW && $level != 0) { echo '
"; echo '
'; echo '', I18N::translate('Google Maps™ preferences'), ''; echo ' | '; echo '', I18N::translate('Geographic data'), ''; echo ' | '; echo '', I18N::translate('Place check'), ''; if (array_key_exists('batch_update', Module::getActiveModules())) { $placelevels = preg_replace('/, ' . I18N::translate('unknown') . '/', ', ', $placelevels); // replace ", unknown" with ", " $placelevels = substr($placelevels, 2); // remove the leading ", " if ($placelevels) { $batchupdate_url = 'module.php?mod=batch_update&mod_action=admin_batch_update&plugin=BatchUpdateSearchReplacePlugin&method=exact&ged=' . WT_GEDCOM . '&search=' . urlencode($placelevels); // exact match echo ' | '; echo '', I18N::translate('Batch update'), ''; } } } echo '
'; echo '
'; if ($STREETVIEW) { $controller->addInlineJavascript(' function update_sv_params(placeid) { var svlati = document.getElementById("sv_latiText").value.slice(0, -1); var svlong = document.getElementById("sv_longText").value.slice(0, -1); var svbear = document.getElementById("sv_bearText").value.slice(0, -1); var svelev = document.getElementById("sv_elevText").value.slice(0, -1); var svzoom = document.getElementById("sv_zoomText").value; win03 = window.open("module.php?mod=googlemap&mod_action=places_edit&action=update_sv_params&placeid="+placeid+"&svlati="+svlati+"&svlong="+svlong+"&svbear="+svbear+"&svelev="+svelev+"&svzoom="+svzoom, "win03", indx_window_specs); if (window.focus) {win03.focus();} } '); global $pl_lati, $pl_long; if ($level >= 1) { $pl_lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $latlng['pl_lati']); // WT_placelocation lati $pl_long = str_replace(array('E', 'W', ','), array('', '-', '.'), $latlng['pl_long']); // WT_placelocation long // Check if Streetview location parameters are stored in database $placeid = $latlng['pl_id']; // Placelocation place id $sv_lat = $latlng['sv_lati']; // StreetView Point of View Latitude $sv_lng = $latlng['sv_long']; // StreetView Point of View Longitude $sv_dir = $latlng['sv_bearing']; // StreetView Point of View Direction (degrees from North) $sv_pitch = $latlng['sv_elevation']; // StreetView Point of View Elevation (+90 to -90 degrees (+=down, -=up) $sv_zoom = $latlng['sv_zoom']; // StreetView Point of View Zoom (0, 1, 2 or 3) // Check if Street View Lati/Long are the default of 0 or null, if so use regular Place Lati/Long to set an initial location for the panda ------------ if (($latlng['sv_lati'] == null && $latlng['sv_long'] == null) || ($latlng['sv_lati'] == 0 && $latlng['sv_long'] == 0)) { $sv_lat = $pl_lati; $sv_lng = $pl_long; } // Set Street View parameters to numeric value if NULL (avoids problem with Google Street View™ Pane not rendering) if ($sv_dir == null) { $sv_dir = 0; } if ($sv_pitch == null) { $sv_pitch = 0; } if ($sv_zoom == null) { $sv_zoom = 1; } ?>
" . WT_Gedcom_Tag::getLabel('LONG') . "" . /* I18N: Compass bearing (in degrees), for street-view mapping */ I18N::translate('Bearing') . "" . /* I18N: Angle of elevation (in degrees), for street-view mapping */ I18N::translate('Elevation') . "" . I18N::translate('Zoom') . " "); if (Auth::isAdmin()) { echo ""; } else { echo "
"; } echo ""; echo "
"; echo "
"; echo $list_latlon; echo ""; echo "
"; echo "
"; } // Next line puts Place hierarchy on new row ----- echo '
$precision2) ? ($precision = $precision1) : ($precision = $precision2); if ($precision == -1) ($level > 3) ? ($precision = 3) : ($precision = $level); elseif ($precision > 5) { $precision = 5; } ?>
  |  
getSetting('GM_PRECISION_0')) echo 'checked'; ?> value="getSetting('GM_PRECISION_0'); ?>"> getSetting('GM_PRECISION_1')) echo 'checked'; ?> value="getSetting('GM_PRECISION_1'); ?>"> getSetting('GM_PRECISION_2')) echo 'checked'; ?> value="getSetting('GM_PRECISION_2'); ?>"> getSetting('GM_PRECISION_3')) echo 'checked'; ?> value="getSetting('GM_PRECISION_3'); ?>"> getSetting('GM_PRECISION_4')) echo 'checked'; ?> value="getSetting('GM_PRECISION_4'); ?>"> = $this->getSetting('GM_PRECISION_5')) echo 'checked'; ?> value="getSetting('GM_PRECISION_5'); ?>">

<?php echo /* I18N: The emblem of a country or region */ I18N::translate('Flag'); ?>     

restrictAccess(Auth::isAdmin()); if ($action == 'ExportFile' && Auth::isAdmin()) { Zend_Session::writeClose(); $tmp = $this->placeIdToHierarchy($parent); $maxLevel = $this->getHighestLevel(); if ($maxLevel > 8) $maxLevel = 8; $tmp[0] = 'places'; $outputFileName = preg_replace('/[:;\/\\\(\)\{\}\[\] $]/', '_', implode('-', $tmp)) . '.csv'; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $outputFileName . '"'); echo '"', I18N::translate('Level'), '";"', I18N::translate('Country'), '";'; if ($maxLevel > 0) echo '"', I18N::translate('State'), '";'; if ($maxLevel > 1) echo '"', I18N::translate('County'), '";'; if ($maxLevel > 2) echo '"', I18N::translate('City'), '";'; if ($maxLevel > 3) echo '"', I18N::translate('Place'), '";'; if ($maxLevel > 4) echo '"', I18N::translate('Place'), '";'; if ($maxLevel > 5) echo '"', I18N::translate('Place'), '";'; if ($maxLevel > 6) echo '"', I18N::translate('Place'), '";'; if ($maxLevel > 7) echo '"', I18N::translate('Place'), '";'; echo '"', I18N::translate('Longitude'), '";"', I18N::translate('Latitude'), '";'; echo '"', I18N::translate('Zoom level'), '";"', I18N::translate('Icon'), '";', WT_EOL; $this->outputLevel($parent); exit; } $controller ->setPageTitle(I18N::translate('Google Maps™')) ->pageHeader(); ?>
execute(array(WT_GED_ID, WT_GED_ID)) ->fetchOneColumn(); foreach ($gedcom_records as $gedrec) { $i = 1; $placerec = get_sub_record(2, '2 PLAC', $gedrec, $i); while (!empty($placerec)) { if (preg_match("/2 PLAC (.+)/", $placerec, $match)) { $placelist[$j] = array(); $placelist[$j]['place'] = trim($match[1]); if (preg_match("/4 LATI (.*)/", $placerec, $match)) { $placelist[$j]['lati'] = trim($match[1]); if (($placelist[$j]['lati'][0] != 'N') && ($placelist[$j]['lati'][0] != 'S')) { if ($placelist[$j]['lati'] < 0) { $placelist[$j]['lati'][0] = 'S'; } else { $placelist[$j]['lati'] = 'N' . $placelist[$j]['lati']; } } } else $placelist[$j]['lati'] = null; if (preg_match("/4 LONG (.*)/", $placerec, $match)) { $placelist[$j]['long'] = trim($match[1]); if (($placelist[$j]['long'][0] != 'E') && ($placelist[$j]['long'][0] != 'W')) { if ($placelist[$j]['long'] < 0) { $placelist[$j]['long'][0] = 'W'; } else { $placelist[$j]['long'] = 'E' . $placelist[$j]['long']; } } } else $placelist[$j]['long'] = null; $j = $j + 1; } $i = $i + 1; $placerec = get_sub_record(2, '2 PLAC', $gedrec, $i); } } asort($placelist); $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k=>$place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $j = $j + 1; } elseif (($place['place'] == $prevPlace) && (($place['lati'] != $prevLati) || ($place['long'] != $prevLong))) { if (($placelistUniq[$j - 1]['lati'] == 0) || ($placelistUniq[$j - 1]['long'] == 0)) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; } elseif (($place['lati'] != '0') || ($place['long'] != '0')) { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '
'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $highestIndex = $this->getHighestIndex(); $default_zoom_level = array(4, 7, 10, 12); foreach ($placelistUniq as $k=>$place) { $parent = preg_split('/ *, */', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { if (!isset($default_zoom_level[$i])) $default_zoom_level[$i] = $default_zoom_level[$i - 1]; $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ?") ->execute(array($i, $parent_id, $escparent)) ->fetchOneRow(); if ($i < count($parent) - 1) { // Create higher-level places, if necessary if (empty($row)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom) VALUES (?, ?, ?, ?, ?)") ->execute(array($highestIndex, $parent_id, $i, $escparent, $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '
'; $parent_id = $highestIndex; } else { $parent_id = $row->pl_id; } } else { // Create lowest-level place, if necessary if (empty($row->pl_id)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom) VALUES (?, ?, ?, ?, ?, ?, ?)") ->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '
'; } else { if (empty($row->pl_long) && empty($row->pl_lati) && $place['lati'] != '0' && $place['long'] != '0') { Database::prepare("UPDATE `##placelocation` SET pl_lati=?, pl_long=? WHERE pl_id=?") ->execute(array($place['lati'], $place['long'], $row->pl_id)); echo Filter::escapeHtml($escparent), '
'; } } } } } $parent = 0; } if ($action === 'ImportFile') { $placefiles = $this->findFiles(WT_MODULES_DIR . 'googlemap/extra'); sort($placefiles); ?>
0) { ?>


iso3166() as $key=>$value) { $country_names[$key] = I18N::translate($key); } if (isset($_POST['cleardatabase'])) { Database::exec("DELETE FROM `##placelocation` WHERE 1=1"); } if (!empty($_FILES['placesfile']['tmp_name'])) { $lines = file($_FILES['placesfile']['tmp_name']); } elseif (!empty($_REQUEST['localfile'])) { $lines = file(WT_MODULES_DIR . 'googlemap/extra' . $_REQUEST['localfile']); } // Strip BYTE-ORDER-MARK, if present if (!empty($lines[0]) && substr($lines[0], 0, 3) === WT_UTF8_BOM) { $lines[0] = substr($lines[0], 3); } asort($lines); $highestIndex = $this->getHighestIndex(); $placelist = array(); $j = 0; $maxLevel = 0; foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if ($fieldrec[0] > $maxLevel) $maxLevel = $fieldrec[0]; } $fields = count($fieldrec); $set_icon = true; if (!is_dir(WT_MODULES_DIR . 'googlemap/places/flags/')) { $set_icon = false; } foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if (is_numeric($fieldrec[0]) && $fieldrec[0] <= $maxLevel) { $placelist[$j] = array(); $placelist[$j]['place'] = ''; for ($ii = $fields - 4; $ii > 1; $ii--) { if ($fieldrec[0] > $ii - 2) $placelist[$j]['place'] .= $fieldrec[$ii] . ','; } foreach ($country_names as $countrycode => $countryname) { if ($countrycode == strtoupper($fieldrec[1])) { $fieldrec[1] = $countryname; break; } } $placelist[$j]['place'] .= $fieldrec[1]; $placelist[$j]['long'] = $fieldrec[$fields - 4]; $placelist[$j]['lati'] = $fieldrec[$fields - 3]; $placelist[$j]['zoom'] = $fieldrec[$fields - 2]; if ($set_icon) { $placelist[$j]['icon'] = trim($fieldrec[$fields - 1]); } else { $placelist[$j]['icon'] = ''; } $j = $j + 1; } } $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k=>$place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $placelistUniq[$j]['zoom'] = $place['zoom']; $placelistUniq[$j]['icon'] = $place['icon']; $j = $j + 1; } elseif (($place['place'] == $prevPlace) && (($place['lati'] != $prevLati) || ($place['long'] != $prevLong))) { if (($placelistUniq[$j - 1]['lati'] == 0) || ($placelistUniq[$j - 1]['long'] == 0)) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; $placelistUniq[$j - 1]['zoom'] = $place['zoom']; $placelistUniq[$j - 1]['icon'] = $place['icon']; } elseif (($place['lati'] != '0') || ($place['long'] != '0')) { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '
'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $default_zoom_level = array(); $default_zoom_level[0] = 4; $default_zoom_level[1] = 7; $default_zoom_level[2] = 10; $default_zoom_level[3] = 12; foreach ($placelistUniq as $k=>$place) { $parent = explode(',', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom, pl_icon FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ? ORDER BY pl_place") ->execute(array($i, $parent_id, $escparent)) ->fetchOneRow(); if (empty($row)) { // this name does not yet exist: create entry if (!isset($_POST['updateonly'])) { $highestIndex = $highestIndex + 1; if (($i + 1) == count($parent)) { $zoomlevel = $place['zoom']; } elseif (isset($default_zoom_level[$i])) { $zoomlevel = $default_zoom_level[$i]; } else { $zoomlevel = $this->getSetting('GM_MAX_ZOOM'); } if (($place['lati'] == '0') || ($place['long'] == '0') || (($i + 1) < count($parent))) { Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?)") ->execute(array($highestIndex, $parent_id, $i, $escparent, $zoomlevel, $place['icon'])); } else { //delete leading zero $pl_lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $place['lati']); $pl_long = str_replace(array('E', 'W', ','), array('', '-', '.'), $place['long']); if ($pl_lati >= 0) { $place['lati'] = 'N' . abs($pl_lati); } elseif ($pl_lati < 0) { $place['lati'] = 'S' . abs($pl_lati); } if ($pl_long >= 0) { $place['long'] = 'E' . abs($pl_long); } elseif ($pl_long < 0) { $place['long'] = 'W' . abs($pl_long); } Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") ->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $zoomlevel, $place['icon'])); } $parent_id = $highestIndex; } } else { $parent_id = $row->pl_id; if ((isset($_POST['overwritedata'])) && ($i + 1 == count($parent))) { Database::prepare("UPDATE `##placelocation` SET pl_lati=?, pl_long=?, pl_zoom=?, pl_icon=? WHERE pl_id=?") ->execute(array($place['lati'], $place['long'], $place['zoom'], $place['icon'], $parent_id)); } else { if ((($row->pl_long == '0') || ($row->pl_long == null)) && (($row->pl_lati == '0') || ($row->pl_lati == null))) { Database::prepare("UPDATE `##placelocation` SET pl_lati=?, pl_long=? WHERE pl_id=?") ->execute(array($place['lati'], $place['long'], $parent_id)); } if (empty($row->pl_icon) && !empty($place['icon'])) { Database::prepare("UPDATE `##placelocation` SET pl_icon=? WHERE pl_id=?") ->execute(array($place['icon'], $parent_id)); } } } } } $parent = 0; } if ($action == 'DeleteRecord') { $exists = Database::prepare("SELECT 1 FROM `##placelocation` WHERE pl_parent_id=?") ->execute(array($deleteRecord)) ->fetchOne(); if (!$exists) { Database::prepare("DELETE FROM `##placelocation` WHERE pl_id=?") ->execute(array($deleteRecord)); } else { echo '
', I18N::translate('Location not removed: this location contains sub-locations'), '
'; } } ?> '; $where_am_i = $this->placeIdToHierarchy($parent); foreach (array_reverse($where_am_i, true) as $id=>$place) { if ($id == $parent) { if ($place != 'Unknown') { echo Filter::escapeHtml($place); } else { echo I18N::translate('unknown'); } } else { echo ''; if ($place != 'Unknown') { echo Filter::escapeHtml($place), ''; } else { echo I18N::translate('unknown'), ''; } } echo ' - '; } echo '', I18N::translate('Top level'), ''; echo '
'; echo ''; echo '
'; echo '

'; echo I18N::translate('By default, the list shows only those places which can be found in your family trees. You may have details for other places, such as those imported in bulk from an external file. Selecting this option will show all places, including ones that are not currently used.'); echo ' '; echo I18N::translate('If you have a large number of inactive places, it can be slow to generate the list.'); echo '

'; echo '
'; $placelist = $this->getPlaceListLocation($parent, $inactive); echo '
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; if (count($placelist) == 0) echo ''; foreach ($placelist as $place) { echo ''; else echo I18N::translate('unknown'), ''; echo ''; echo ''; echo ''; echo ''; echo ''; $noRows = Database::prepare("SELECT COUNT(pl_id) FROM `##placelocation` WHERE pl_parent_id=?") ->execute(array($place['place_id'])) ->fetchOne(); if ($noRows == 0) { ?>
', WT_Gedcom_Tag::getLabel('PLAC'), '', WT_Gedcom_Tag::getLabel('LATI'), '', WT_Gedcom_Tag::getLabel('LONG'), '', I18N::translate('Zoom level'), '', I18N::translate('Icon'), ''; echo I18N::translate('Edit'), '', I18N::translate('Delete'), '
', I18N::translate('No places found'), '
'; if ($place['place'] != 'Unknown') echo Filter::escapeHtml($place['place']), '', $place['lati'], '', $place['long'], '', $place['zoom'], ''; if (($place['icon'] == null) || ($place['icon'] == '')) { if (($place['lati'] == null) || ($place['long'] == null) || (($place['lati'] == '0') && ($place['long'] == '0'))) { echo ''; } else { echo ''; } } else { echo ''; } echo '
'; echo ''; ?>
Click and drag the marker.