Source of file GoogleMap.php
Size: 28,054 Bytes - Last Modified: 2021-12-23T10:41:51+00:00
/var/www/docs.ssmods.com/process/src/code/viewableData/GoogleMap.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871 | <?php /** * This is the basic engine for the Google Map * * There are three options * 1. setAddress: set address * 2. setPageDataObjectSet: set Page Data List (who have geo points as children) * 3. setPoints: set Points Directly Class = GoogleMapLocationsObject * * Extras include: * 1. setTitleOfMap: set title * 2. setWhereStatementDescription: set where statement * 3. setFilteredClassNameArray: set an array of classnames * * The static configs are explained in googlemap/_config/googlemap.yml.example * * **/ class GoogleMap extends ViewableData { ################################ # SETTINGS ################################ /* BASIC MAP SETTINGS */ private static $api_version = '3'; private static $google_map_api_key = ""; private static $default_latitude = 0.000000001; //MOVE TO SITECONFIG private static $default_longitude = 0.0000000001; //MOVE TO SITECONFIG private static $default_zoom = 2; //MOVE TO SITECONFIG private static $google_map_width = 0; private static $google_map_height = 0; /* MAP CONTROLS*/ private static $map_type_default = 0; //MOVE TO SITECONFIG private static $view_finder_size = 100; //MOVE TO SITECONFIG private static $map_add_type_control = false; //MOVE TO SITECONFIG private static $map_control_size_one_to_three = 3; //MOVE TO SITECONFIG private static $map_scale_info_size_in_pixels = 100; //MOVE TO SITECONFIG /* INFORMATION AROUND THE MAP */ private static $default_title = ""; //MOVE TO SITECONFIG private static $default_where_statement_description = ""; //MOVE TO SITECONFIG private static $no_status_at_all = true; //MOVE TO SITECONFIG private static $add_kml_link = false; //MOVE TO SITECONFIG private static $hidden_layers_removed_from_list = false; private static $change_page_title = false; //MOVE TO SITECONFIG private static $number_of_items_before_showing_list = 1; //MOVE TO SITECONFIG private static $main_div_id = "GoogleMapDiv"; private static $title_div_id = ""; private static $side_bar_div_id = ""; private static $drop_down_div_id =""; private static $layer_list_div_id = ""; private static $directions_div_id = ""; private static $status_div_id = ""; /* INFOWINDOW*/ private static $info_window_options = "{maxWidth:280, zoomLevel:17, mapTypeId: google.maps.MapTypeId.HYBRID}"; private static $add_antipodean = false; //MOVE TO SITECONFIG private static $add_directions = false; //MOVE TO SITECONFIG private static $add_current_address_finder_in_marker = false; //MOVE TO SITECONFIG private static $add_zoom_in_button = true; //MOVE TO SITECONFIG private static $ajax_info_window_text = "View Details"; //MOVE TO SITECONFIG /* MARKERS */ private static $add_points_to_map = false; private static $add_delete_marker_button = ""; private static $marker_options = "{bouncy:true,title: \"click me\"}"; private static $preload_images = false; /* ICONS */ private static $default_icon_url = ""; private static $icon_folder = "/googlemap/images/icons/"; private static $icon_width = 20; private static $icon_height = 34; private static $icon_extension = "png"; private static $icon_max_count = 12; /* POLYS */ private static $line_colour = "#000"; private static $line_width = 12; private static $line_opacity = 0.5; private static $fill_colour = "#ffccff"; private static $fill_opacity = 0.5; private static $poly_icon = ""; /* STATIC MAP */ private static $static_map_settings = "maptype=roadmap"; private static $static_icon = ""; private static $save_static_map_locally = false; /* ADDRESS FINDER */ private static $add_address_finder = false; //MOVE TO SITECONFIG private static $default_country_code = "nz"; // see https://developers.google.com/maps/documentation/geocoding/#RegionCodes private static $number_shown_in_around_me = 7; //MOVE TO SITECONFIG private static $max_radius_for_show_around_me = 20000; /* DIRECTIONS SETTINGS */ private static $style_sheet_url = ""; private static $locale_for_results = "en_NZ"; /* SERVER SETTINGS */ private static $lng_form_field_id = ""; private static $lat_form_field_id = ""; ################################ # TEMPATE METHODS ################################ /** * @return String */ public function Link() { $page = Controller::curr(); if ($page) { return $page->Link(); } } /** * function name for map... * @var String */ protected $myMapFunctionName = "GMO"; public function setMyMapFunctionName($a) { $this->myMapFunctionName = $s; } public function MyMapFunctionName() { return $this->getMyMapFunctionName(false); } public function MyInstanceName() { return $this->getMyMapFunctionName(true); } public function getMyMapFunctionName($instanceName = false) { if ($instanceName) { $var = 'load_my_map_'.$this->myMapFunctionName; } else { $var = $this->myMapFunctionName; } return $var; } /** * title of map * @var string */ protected $titleOfMap = ""; public function setTitleOfMap($s) { $this->titleOfMap = $s; } public function TitleOfMap() { return $this->getTitleOfMap(); } public function getTitleOfMap() { return $this->titleOfMap; } /** * title of map * @var string */ protected $noDataPointsMessage = ""; public function setNoDataPointsMessage($s) { $this->noDataPointsMessage = $s; } public function NoDataPointsMessage() { return $this->getNoDataPointsMessage(); } public function getNoDataPointsMessage() { return $this->noDataPointsMessage; } /** * used for static and non-static maps, hence defined only once. * @return string */ public function GoogleMapDivID() { return Config::inst()->get("GoogleMap", "main_div_id"); } /** * used for static and non-static maps, hence defined only once. * @return Int */ public function GoogleMapWidth() { return Config::inst()->get("GoogleMap", "google_map_width"); } /** * used for static and non-static maps, hence defined only once. * @return Int */ public function GoogleMapHeight() { return Config::inst()->get("GoogleMap", "google_map_height"); } /** * @return Boolean */ public function AddAddressFinder() { return Config::inst()->get("GoogleMap", "add_address_finder"); } /** * @return Boolean */ public function CanEdit($member = null) { if ($this->getUpdateServerUrlDragend()) { if (Injector::inst()->get("GoogleMapLocationsObject")->canEdit($member)) { return true; } } } /** * @return String */ public function TitleDivID() { return Config::inst()->get("GoogleMap", "title_div_id"); } /** * @return String */ public function SideBarDivId() { return Config::inst()->get("GoogleMap", "side_bar_div_id"); } /** * @return String */ public function DropDownDivId() { return Config::inst()->get("GoogleMap", "drop_down_div_id"); } /** * @return String */ public function LayerListDivId() { return Config::inst()->get("GoogleMap", "layer_list_div_id"); } /** * @return String */ public function DirectionsDivId() { return Config::inst()->get("GoogleMap", "directions_div_id"); } /** * @return String */ public function StatusDivId() { return Config::inst()->get("GoogleMap", "status_div_id"); } /** * * @var Boolean */ public function AllowAddPointsToMap() { $this->Config()->update("add_points_to_map", true); } /** * @var ArrayList */ protected $processedDataPointsForTemplate = null; public function setProcessedDataPointsForTemplate($s) { $this->processedDataPointsForTemplate = $s; } public function ProcessedDataPointsForTemplate() { return $this->getProcessedDataPointsForTemplate(); } public function getProcessedDataPointsForTemplate() { return $this->processedDataPointsForTemplate; } /** * @var string */ protected $dataPointsXML = ''; protected function DataPointsXML() { return $this->getDataPointsXML(); } protected function getDataPointsXML() { $this->createDataPoints(); return $this->dataPointsXML; } ################################ # SETUP: LAYER MANAGEMENT ################################ /** * @var ArrayList */ protected $extraLayers = null; public function setExtraLayer($a) { $this->extraLayers = $a; } public function getExtraLayers() { return $this->extraLayers; } /** * @param String $title * @param String $link */ public function addExtraLayer($title, $link) { if (!$this->getExtraLayers()) { $this->extraLayers = new ArrayList(); } $this->extraLayers->push( new ArrayData( array( "Title" => $title, "Link" => $link, "MyInstanceName" => $this->MyInstanceName() ) ) ); } /** * * @return ArrayList */ public function AllExtraLayers() { return $this->getExtraLayers(); } /** * @var Array * Link => Title */ protected $linksForData = array(); public function setLinksForData($a) { $this->linksForData = $a; } public function getLinksForData() { return $this->linksForData; } /** * @param string $linkForData * @param string $title */ public function addLayer($linkForData, $title) { $this->linksForData[$linkForData] = $title; } ################################ # SETUP: FILTERS AND POINTS PROVIDERS ################################ /** * address being searched for * @var String */ protected $address = ""; public function setAddress($v) { $this->address = Convert::raw2js($v); } public function getAddress($v) { return $this->address; } /** * sets the list of points through a list of parent pages * affected variable is: points * @param DataList | ArrayList $pageDataList */ public function setPageDataObjectSet($pageDataList) { if ($pageDataList->count()) { if ($pageDataList instanceof SS_List) { $array = $pageDataList->map("ID", "ID"); } elseif ($pageDataList instanceof DataList) { $array = $pageDataList->map("ID", "ID")->toArray(); } else { user_error("Wrong format for pageDataList"); } $this->points = GoogleMapLocationsObject::get()->filter(array("ParentID" => $array)); $pageDataList = null; } } /** * @var DataList */ protected $points = null; public function setPoints($s) { $this->points = $s; } public function getPoints() { return $this->points; } /** * a description of how the points were selected ... * @var String */ protected $whereStatementDescription = ""; public function setWhereStatementDescription($s) { $this->whereStatementDescription = $s; } public function getWhereStatementDescription() { return $this->whereStatementDescription; } /** * filter for class names * @var Array */ protected $filteredClassNameArray = array(); public function setFilteredClassNameArray($a) { $this->filteredClassNameArray = $s; } public function getFilteredClassNameArray() { return $this->filteredClassNameArray; } ################################ # MAP CHANGES ################################ /** * @var String */ protected $updateServerUrlAddressSearchPoint = "/googlemap/showaroundmexml/"; public function setUpdateServerUrlAddressSearchPoint($v) { $this->updateServerUrlAddressSearchPoint = Director::absoluteBaseURL().$v; } public function getUpdateServerURLAddressSearchPoint() { return $this->updateServerUrlAddressSearchPoint; } /** * @var String */ protected $updateServerUrlDragend = ""; public function setUpdateServerUrlDragend($v) { $this->updateServerUrlDragend = Director::absoluteBaseURL().$v; } public function getUpdateServerUrlDragend() { return $this->updateServerUrlDragend; } ################################ # LOADING ################################ /** * this is a hack to avoid having multiple includes * @var Boolean */ private static $_includes_are_done = false; public function loadGoogleMap() { $js = ''; $this->loadDefaults(); if (!self::$_includes_are_done) { Requirements::themedCSS("googleMap", 'googlemap'); Requirements::javascript(THIRDPARTY_DIR."/jquery/jquery.js"); $variableName = $this->getMyMapFunctionName(false); $instanceName = $this->getMyMapFunctionName(true); Requirements::javascript("googlemap/javascript/loadAjaxInfoWindow.js"); Requirements::insertHeadTags('<style type="text/css">v\:* {behavior:url(#default#VML);}</style>', "GoogleMapCustomHeadTag"); Requirements::javascript( "//maps.googleapis.com/maps/api/js" ."?v=".Config::inst()->get("GoogleMap", "api_version") ."&libraries=places" ."&key=".Config::inst()->get('GoogleMap', 'google_map_api_key') ); Requirements::javascript(THIRDPARTY_DIR.'/jquery-form/jquery.form.js'); Requirements::javascript("googlemap/javascript/googleMaps.js"); $js .= $this->createJavascript(); Requirements::customScript($js, "GoogleMapCustomScript"); self::$_includes_are_done = true; } return $this; } ################################ # DATA POINTS MASSAGE ################################ /** * sorts points by Latitude * @param boolean $reverse * * @return ArrayList */ protected function orderItemsByLatitude($reverse = false) { $unsortedSet = $this->getProcessedDataPointsForTemplate(); $sortedSet = new ArrayList(); if ($unsortedSet->count()) { foreach ($unsortedSet as $item) { $tempArray[$item->Latitude] = $item; } } ksort($tempArray); //not sure why this is a bit counter intuitive. //north to south is from high to low ... if (!$reverse) { $tempArray = array_reverse($tempArray); } foreach ($tempArray as $item) { $sortedSet->push($item); } return $sortedSet; } /** * * @return Int */ public function getPointCount() { if ($processedPoints = $this->getProcessedDataPointsForTemplate()) { return $processedPoints->count(); } elseif ($points = $this->getPoints()) { return $points->count(); } return 0; } /** * @return Boolean */ public function EnoughPointsForAList() { return $this->getPointCount() >= $this->Config()->get("number_of_items_before_showing_list") ? true : false; } /** * must be public * does not return the datapoints XML * but loads it into variables... * @return Boolean */ public function createDataPoints() { if ($this->dataPointsXML === '') { $this->loadDefaults(); $idArray = array(); $bestZoom = $this->Config()->get("default_zoom"); $averageLatitude = 0; $averageLongitude = 0; $count = 0; $pointsXml = ''; //width $totalCount = $this->getPointCount(); $filterFree = count($this->filteredClassNameArray) ? false : true; $averageLongitudeArray = array(); $averageLatitudeArray = array(); if ($totalCount > 0 && $totalCount < 10000) { $this->processedDataPointsForTemplate = new ArrayList(); foreach ($this->getPoints() as $dataPoint) { $dataPoint->addParentData(); if ($filterFree || in_array($dataPoint->ClassName, $this->filteredClassNameArray)) { if (! in_array($dataPoint->ID, $idArray)) { if ($dataPoint->Longitude && $dataPoint->Latitude) { $dataLine = '<Point><coordinates>'.$dataPoint->Longitude.','.$dataPoint->Latitude.'</coordinates></Point>'; $link = ''; if ($dataPoint->Link) { $link = $dataPoint->getAjaxInfoWindowLink(); } $staticIcon = ''; if ($dataPoint->staticIcon) { $staticIcon = $dataPoint->staticIcon; } else { $staticIcon = $this->Config()->get("static_icon"); } $center = round($dataPoint->Latitude, 6).",".round($dataPoint->Longitude, 6); //get the center IF there is only one point... if (!$count) { $defaultCenter = $center; } if (!$dataPoint->Name) { $dataPoint->Name = "no name"; } $pointsXml .= '<Placemark>'. '<id>'.$dataPoint->ID.'</id>'. '<name>'.Convert::raw2xml($dataPoint->Name).'</name>'. $dataLine. '<description><![CDATA[ '.$dataPoint->getAjaxInfoWindowLink().']]></description>'. '</Placemark>'; $this->processedDataPointsForTemplate->push($dataPoint); $averageLatitudeArray[] = $dataPoint->Longitude; $averageLongitudeArray[] = $dataPoint->Latitude; $count++; } } } $idArray[$dataPoint->ID] = $dataPoint->ID; } $averageLongitude = array_sum($averageLongitudeArray) / count($averageLongitudeArray); $averageLatitude = array_sum($averageLatitudeArray) / count($averageLatitudeArray); $this->processedDataPointsForTemplate = $this->orderItemsByLatitude($this->processedDataPointsForTemplate); } if (! $pointsXml) { $pointsXml = '<errormessage>'.$this->getNoDataPointsMessage().'</errormessage>'; } if (!$averageLongitude) { $averageLongitude = $this->config()->get("default_longitude"); } if (!$averageLatitude) { $averageLatitude = $this->config()->get("default_latitude"); } $this->dataPointsXML = '<mapinfo>'.'<title>'.$this->getTitleOfMap().'</title>' .'<longitude>'.number_format($averageLongitude - 0, 12, ".", "").'</longitude>' .'<latitude>'.number_format($averageLatitude - 0, 9, ".", "").'</latitude>' .'<zoom>'.$bestZoom.'</zoom>' .'<pointcount>'.$count.'</pointcount>' .'<info>'.$this->getWhereStatementDescription().'</info>' .'</mapinfo>' .$pointsXml; } return true; } /** * @param String staticVariablename * @return String (Javascript) */ protected function createJavascript() { $variableName = $this->getMyMapFunctionName(false); $instanceName = $this->getMyMapFunctionName(true); $js = ' if(typeof GoogleMapConstructors === "undefined"){ GoogleMapConstructors = []; } GoogleMapConstructors.push( { divID: "'.$this->GoogleMapDivID().'", layers: [], address: "", options: { /* HELPDIVS */ sideBarId:"'.$this->config()->get("side_bar_div_id").'", dropBoxId:"'.$this->config()->get("drop_down_div_id").'", titleId:"'.$this->config()->get("title_div_id").'", layerListId:"'.$this->config()->get("layer_list_div_id").'", directionsDivId:"'.$this->config()->get("directions_div_id").'", statusDivId:"'.$this->config()->get("status_div_id").'", noStatusAtAll:'.$this->showFalseOrTrue($this->config()->get("no_status_at_all")).', addKmlLink:'.$this->showFalseOrTrue($this->config()->get("add_kml_link")).', hiddenLayersRemovedFromList:'.$this->showFalseOrTrue($this->config()->get("hidden_layers_removed_from_list")).', /* PAGE*/ changePageTitle:'.$this->showFalseOrTrue($this->config()->get("change_page_title")).', defaultTitle:"'.$this->config()->get("default_title").'", /* INFOWINDOW*/ infoWindowOptions:'.$this->config()->get("info_window_options").', addAntipodean:'.$this->showFalseOrTrue($this->config()->get("add_antipodean")).', addDirections:'.$this->showFalseOrTrue($this->config()->get("add_directions")).', addCurrentAddressFinder:'.$this->showFalseOrTrue($this->config()->get("add_current_address_finder_in_marker")).', addZoomInButton:"'.$this->config()->get("add_zoom_in_button").'", /* MARKER */ addPointsToMap:'.$this->showFalseOrTrue($this->config()->get("add_points_to_map")).', addDeleteMarkerButton:"'.$this->config()->get("add_delete_marker_button").'", markerOptions: '.$this->config()->get("marker_options").', preloadImages:'.$this->showFalseOrTrue($this->config()->get("preload_images")).', /* ICONS */ defaultIconUrl: "'.$this->config()->get("default_icon_url").'", iconFolder: "'.$this->config()->get("icon_folder").'", iconWidth:'.$this->config()->get("icon_width").', iconHeight:'.$this->config()->get("icon_height").', iconExtension:"'.$this->config()->get("icon_extension").'", iconMaxCount:'.$this->config()->get("icon_max_count").', /* POLYS */ lineColour: "'.$this->config()->get("line_colour").'", lineWidth: "'.$this->config()->get("line_width").'", lineOpacity: "'.$this->config()->get("line_opacity").'", fillColour: "'.$this->config()->get("fill_colour").'", fillOpacity: "'.$this->config()->get("fill_opacity").'", polyIcon: "'.$this->config()->get("poly_icon").'", /* MAP*/ mapTypeDefault: '.intval($this->config()->get("map_type_default")-0).', viewFinderSize:'.intval($this->config()->get("view_finder_size") - 0).', mapAddTypeControl:'.$this->showFalseOrTrue($this->config()->get("map_add_type_control")).', mapControlSizeOneToThree:'.$this->config()->get("map_control_size_one_to_three").', mapScaleInfoSizeInPixels:'.intval($this->config()->get("map_scale_info_size_in_pixels") - 0).', /* START POSITION */ defaultLatitude:'.number_format($this->config()->get("default_latitude") - 0, 9, ".", "").', defaultLongitude:'.number_format($this->config()->get("default_longitude") - 0, 12, ".", "").', defaultZoom:'.intval($this->config()->get("default_zoom") - 0).', /* SERVER INTERACTION */ updateServerUrlAddressSearchPoint: "'.$this->getUpdateServerUrlAddressSearchPoint(). '", updateServerUrlDragend: "'.$this->getUpdateServerUrlDragend().'", latFormFieldId:"'.$this->config()->get("lat_form_field_id").'", lngFormFieldId:"'.$this->config()->get("lng_form_field_id").'", /* ADDRESS FORM */ addAddressFinder:'.$this->showFalseOrTrue($this->config()->get("add_address_finder")).', defaultCountryCode:"'.$this->config()->get("default_country_code").'", /* DIRECTIONS */ styleSheetUrl: "'.$this->config()->get("style_sheet_url").'", localeForResults: "'.$this->config()->get("locale_for_results").'" } } );'; if ($this->linksForData && count($this->linksForData)) { foreach ($this->linksForData as $link => $title) { $js .= ' GoogleMapConstructors[GoogleMapConstructors.length-1].layers.push( { link: '.Convert::raw2json(Director::absoluteURL($link)).', title: '.Convert::raw2json($title).' } );'; } } elseif ($this->address) { $js .= ' GoogleMapConstructors[GoogleMapConstructors.length-1].address = \''.$this->address.'\''; } return $js; } /** * turns 0 into false and 1 into true * @param Mixed * @return string (true|false) */ protected function showFalseOrTrue($v) { if ($v && $v !== "false" && $v !== "0" && $v !== 0) { return "true"; } else { return "false"; } } /** * load some defaults */ protected function loadDefaults() { if (!isset($this->whereStatementDescription)) { $this->whereStatementDescription = $this->Config()->get("default_where_statement_description"); } if (!isset($this->titleOfMap) || !$this->titleOfMap) { $this->titleOfMap = $this->Config()->get("default_title"); } } } |