"http://maps.google.com/maps?q=@lat@,+@long@&iwloc=A&hl=en",
"Google Earth" => "@wwwroot@/mod/data/field/latlong/kml.php?d=@dataid@&fieldid=@fieldid@&rid=@recordid@",
"Geabios" => "http://www.geabios.com/html/services/maps/PublicMap.htm?lat=@lat@&lon=@long@&fov=0.3&title=Moodle%20data%20item",
"OpenStreetMap" => "http://www.openstreetmap.org/index.html?lat=@lat@&lon=@long@&zoom=11",
"Multimap" => "http://www.multimap.com/map/browse.cgi?scale=200000&lon=@long@&lat=@lat@&icon=x"
);
// Other map sources listed at http://kvaleberg.com/extensions/mapsources/index.php?params=51_30.4167_N_0_7.65_W_region:earth
public function supports_preview(): bool {
return true;
}
public function get_data_content_preview(int $recordid): stdClass {
return (object)[
'id' => 0,
'fieldid' => $this->field->id,
'recordid' => $recordid,
'content' => 41.391205,
'content1' => 2.163873,
'content2' => null,
'content3' => null,
'content4' => null,
];
}
function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT;
$lat = '';
$long = '';
if ($formdata) {
$fieldname = 'field_' . $this->field->id . '_0';
$lat = $formdata->$fieldname;
$fieldname = 'field_' . $this->field->id . '_1';
$long = $formdata->$fieldname;
} else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
$lat = $content->content;
$long = $content->content1;
}
}
$str = '
';
$str .= '
';
$str .= '
';
return $str;
}
function display_search_field($value = '') {
global $CFG, $DB;
$varcharlat = $DB->sql_compare_text('content');
$varcharlong= $DB->sql_compare_text('content1');
$latlongsrs = $DB->get_recordset_sql(
"SELECT DISTINCT $varcharlat AS la, $varcharlong AS lo
FROM {data_content}
WHERE fieldid = ?
ORDER BY $varcharlat, $varcharlong", array($this->field->id));
$options = array();
foreach ($latlongsrs as $latlong) {
$latitude = format_float($latlong->la, 4);
$longitude = format_float($latlong->lo, 4);
if ($latitude && $longitude) {
$options[$latlong->la . ',' . $latlong->lo] = $latitude . ' ' . $longitude;
}
}
$latlongsrs->close();
$classes = array('class' => 'accesshide');
$return = html_writer::label(get_string('latlong', 'data'), 'menuf_'.$this->field->id, false, $classes);
$classes = array('class' => 'custom-select');
$return .= html_writer::select($options, 'f_'.$this->field->id, $value, array('' => get_string('menuchoose', 'data')),
$classes);
return $return;
}
public function parse_search_field($defaults = null) {
$param = 'f_'.$this->field->id;
if (empty($defaults[$param])) {
$defaults = array($param => '');
}
return optional_param($param, $defaults[$param], PARAM_NOTAGS);
}
function generate_sql($tablealias, $value) {
global $DB;
static $i=0;
$i++;
$name1 = "df_latlong1_$i";
$name2 = "df_latlong2_$i";
$varcharlat = $DB->sql_compare_text("{$tablealias}.content");
$varcharlong= $DB->sql_compare_text("{$tablealias}.content1");
$latlong[0] = '';
$latlong[1] = '';
$latlong = explode (',', $value, 2);
return array(" ({$tablealias}.fieldid = {$this->field->id} AND $varcharlat = :$name1 AND $varcharlong = :$name2) ",
array($name1=>$latlong[0], $name2=>$latlong[1]));
}
function display_browse_field($recordid, $template) {
global $CFG;
$content = $this->get_data_content($recordid);
if (!$content) {
return '';
}
$lat = $content->content;
if (strlen($lat ?? '') < 1) {
return '';
}
$long = $content->content1;
if (strlen($long ?? '') < 1) {
return '';
}
// We use format_float to display in the regional format.
if ($lat < 0) {
$compasslat = format_float(-$lat, 4) . '°S';
} else {
$compasslat = format_float($lat, 4) . '°N';
}
if ($long < 0) {
$compasslong = format_float(-$long, 4) . '°W';
} else {
$compasslong = format_float($long, 4) . '°E';
}
// Now let's create the jump-to-services link.
$servicesshown = explode(',', $this->field->param1);
// These are the different things that can be magically inserted into URL schemes.
$urlreplacements = array(
'@lat@' => $lat,
'@long@' => $long,
'@wwwroot@' => $CFG->wwwroot,
'@contentid@' => $content->id,
'@dataid@' => $this->data->id,
'@courseid@' => $this->data->course,
'@fieldid@' => $content->fieldid,
'@recordid@' => $content->recordid,
);
if (count($servicesshown) == 1 && $servicesshown[0]) {
$str = " $compasslat $compasslong";
} else if (count($servicesshown) > 1) {
$str = '';
} else {
$str = "$compasslat, $compasslong";
}
return $str;
}
function update_content_import($recordid, $value, $name='') {
$values = explode(" ", $value, 2);
foreach ($values as $index => $value) {
$this->update_content($recordid, $value, $name . '_' . $index);
}
}
function update_content($recordid, $value, $name='') {
global $DB;
$content = new stdClass();
$content->fieldid = $this->field->id;
$content->recordid = $recordid;
// When updating these values (which might be region formatted) we should format
// the float to allow for a consistent float format in the database.
$value = unformat_float($value);
$value = trim($value ?? '');
if (strlen($value) > 0) {
$value = floatval($value);
} else {
$value = null;
}
$names = explode('_', $name);
switch ($names[2]) {
case 0:
// update lat
$content->content = $value;
break;
case 1:
// update long
$content->content1 = $value;
break;
default:
break;
}
if ($oldcontent = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
$content->id = $oldcontent->id;
return $DB->update_record('data_content', $content);
} else {
return $DB->insert_record('data_content', $content);
}
}
function get_sort_sql($fieldname) {
global $DB;
return $DB->sql_cast_char2real($fieldname, true);
}
function export_text_value($record) {
// The content here is from the database and does not require location formating.
return sprintf('%01.4f', $record->content) . ' ' . sprintf('%01.4f', $record->content1);
}
/**
* Check if a field from an add form is empty
*
* @param mixed $value
* @param mixed $name
* @return bool
*/
function notemptyfield($value, $name) {
return isset($value) && !($value == '');
}
/**
* Validate values for this field.
* Both the Latitude and the Longitude fields need to be filled in.
*
* @param array $values The entered values for the lat. and long.
* @return string|bool Error message or false.
*/
public function field_validation($values) {
$valuecount = 0;
// The lat long class has two values that need to be checked.
foreach ($values as $value) {
if (isset($value->value) && !($value->value == '')) {
$valuecount++;
}
}
// If we have nothing filled in or both filled in then everything is okay.
if ($valuecount == 0 || $valuecount == 2) {
return false;
}
// If we get here then only one field has been filled in.
return get_string('latlongboth', 'data');
}
/**
* Return the plugin configs for external functions.
*
* @return array the list of config parameters
* @since Moodle 3.3
*/
public function get_config_for_external() {
// Return all the config parameters.
$configs = [];
for ($i = 1; $i <= 10; $i++) {
$configs["param$i"] = $this->field->{"param$i"};
}
return $configs;
}
public function get_field_params(): array {
global $DB;
$data = parent::get_field_params();
$data['dataid'] = $this->data->id;
if (isset($this->field->param1)) {
$data["param1"] = $this->field->param1;
if (isset($this->linkoutservices)) {
$serviceschosen = explode(',', htmlspecialchars($this->field->param1));
foreach ($this->linkoutservices as $servicename => $serviceurl) {
$servicename = htmlspecialchars($servicename);
$data['latlonglinkservices'][] = [
'name' => $servicename,
'selected' => in_array($servicename, $serviceschosen),
];
unset($serviceschosen[$servicename]);
}
$data['latlonglinkservicessize'] = count($this->linkoutservices);
}
}
$data["otherfields"][] = [
'value' => -1,
'name' => get_string('entry', 'data') . " #",
'selected' => $this->field->param2 == -1,
];
$data['otherfields'][] = [
'value' => -2,
'name' => get_string('latitude', 'data') . "/" . get_string('longitude', 'data'),
'selected' => $this->field->param2 == -2,
];
// Fetch all "suitable" other fields that exist for this database.
$textfields = $DB->get_records('data_fields', ['dataid' => $this->data->id, 'type' => 'text']);
if (count($textfields) > 0) {
$data['otherfieldsoptgroups']['label'] = get_string('latlongotherfields', 'data') . ":";
foreach ($textfields as $textfield) {
$data['otherfieldsoptgroups']['options'][] = [
'value' => $textfield->id,
'name' => $textfield->name,
'selected' => $this->field->param2 == $textfield->id,
];
}
}
if (isset($data['otherfieldsoptgroups'])) {
$data['otherfields'][] = $data['otherfieldsoptgroups'];
}
if (isset($this->field->id)) {
$data['fieldid'] = $this->field->id;
}
return $data;
}
}