/** * Return the generated form output. * @return Form HTML. * @todo: Implement this method */ public static function get_form($args) { $lang = iform_lang_iso_639_2(hostsite_get_user_field('language', 'en')); if (function_exists('iform_load_helpers')) { iform_load_helpers(array('map_helper')); } else { require_once dirname(dirname(__FILE__)) . '/map_helper.php'; } $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']); $r = ''; // setup the map options $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); if (array_key_exists('table', $_GET) && $_GET['table'] == 'sample') { // Use a cUrl request to get the data from Indicia which contains the value we need to filter against // Read the record that was just posted. $fetchOpts = array('dataSource' => 'reports_for_prebuilt_forms/my_dot_map/occurrences_list_2', 'mode' => 'report', 'readAuth' => $readAuth, 'extraParams' => array('sample_id' => $_GET['id'], 'language' => $lang)); // @todo Error handling on the response $occurrence = data_entry_helper::get_report_data($fetchOpts); self::prepare_layer_titles($args, $occurrence); // Add the 3 distribution layers if present. Reverse the order so 1st layer is topmost $layerName = self::build_distribution_layer(3, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } $layerName = self::build_distribution_layer(2, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } $layerName = self::build_distribution_layer(1, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } if ($layerName) { $options['layers'][] = $layerName; } // This is not a map used for input $options['editLayer'] = false; if ($args['hide_grid'] == false) { // Now output a grid of the occurrences that were just saved. $r .= "<table class=\"submission\"><thead><tr><th>" . lang::get('Species') . "</th><th>" . lang::get('Latin Name') . "</th><th>" . lang::get('Abundance') . "</th><th>" . lang::get('Date') . "</th><th>" . lang::get('Spatial Ref') . "</th>" . "</th><th>" . lang::get('Comment') . "</th></tr></thead>\n"; $r .= "<tbody>\n"; foreach ($occurrence as $record) { $r .= '<tr class="biota"><td>' . $record['taxon'] . '</td><td class="binomial"><em>' . $record['preferred_taxon'] . '</em></td><td>' . $record['abundance'] . '</td><td>' . $record['date'] . '</td><td>' . $record['entered_sref'] . '</td>' . $record['comment'] . "</td><td></tr>\n"; } $r .= "</tbody></table>\n"; } } if (!empty($args['add_another_link'])) { $path = $args['add_another_link']; if (count($occurrence) === 1) { $path = str_replace(array('#taxon_meaning_id#', '#external_key#'), array($occurrence[0]['taxon_meaning_id'], $occurrence[0]['external_key']), $path); $parts = explode('?', $path, 2); $parts[0] = url($parts[0]); $path = implode('?', $parts); } $r .= '<a class="indicia-button" href="' . $path . '">' . lang::get('Add another record') . '</a><br/>'; } $r .= '<div id="mapandlegend">'; $r .= map_helper::layer_list(array('id' => 'legend', 'includeSwitchers' => false, 'includeHiddenLayers' => false, 'includeIcons' => true, 'layerTypes' => array('overlay'))); $r .= map_helper::map_panel($options, $olOptions); $r .= '</div>'; return $r; }
/** * Return the generated form output. * @return Form HTML. */ public static function get_form($args) { iform_load_helpers(array('map_helper')); $readAuth = map_helper::get_read_auth($args['website_id'], $args['password']); // setup the map options $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); for ($layer = 1; $layer <= 3; $layer++) { $argTitle = $args["layer_title_{$layer}"]; if (isset($argTitle) && !empty($argTitle)) { //if there is no title then ignore the layer $meaningId = self::get_meaning_id($layer, $args, $readAuth); $taxon = self::get_taxon($meaningId, $readAuth); $layerTitle = str_replace('{species}', $taxon, $argTitle); $layerTitle = str_replace("'", "\\'", $layerTitle); $url = map_helper::$geoserver_url . 'wms'; $argFeature = $args["wms_feature_type_{$layer}"]; $layers = "layers: '{$argFeature}'"; $argStyle = $args["wms_style_{$layer}"]; $style = $argStyle ? ", styles: '{$argStyle}'" : ''; $argWebsite = $args["website_id"]; $filter = ", CQL_FILTER: 'website_id={$argWebsite} AND taxon_meaning_id={$meaningId}"; $argCql = $args["cql_filter_{$layer}"]; if ($argCql) { $arg = str_replace("'", "\\'", $argCql); $filter .= " AND({$argCql})'"; } else { $filter .= "'"; } $script = " var distLayer{$layer} = new OpenLayers.Layer.WMS("; $script .= "'{$layerTitle}', '{$url}',"; $script .= "{" . "{$layers}, transparent: true {$filter} {$style}},"; $script .= "{isBaseLayer: false, sphericalMercator: true, singleTile: true}"; $script .= ");\n"; map_helper::$onload_javascript .= $script; $options['layers'][] = "distLayer{$layer}"; } } // This is not a map used for input $options['editLayer'] = false; // output a legend $r .= map_helper::layer_list(array('includeSwitchers' => true, 'includeHiddenLayers' => true)); // output a map $r .= map_helper::map_panel($options, $olOptions); // Set up a page refresh for dynamic update of the map at set intervals if ($args['refresh_timer'] !== 0 && is_numeric($args['refresh_timer'])) { // is_int prevents injection if (isset($args['load_on_refresh']) && !empty($args['load_on_refresh'])) { map_helper::$javascript .= "setTimeout('window.location=\"" . $args['load_on_refresh'] . "\";', " . $args['refresh_timer'] . "*1000 );\n"; } else { map_helper::$javascript .= "setTimeout('window.location.reload( false );', " . $args['refresh_timer'] . "*1000 );\n"; } } return $r; }
/** * Return the Indicia form code * @param array $args Input parameters. * @param array $node Drupal node object * @param array $response Response from Indicia services after posting. * @return HTML string */ public static function get_form($args, $node, $response) { iform_load_helpers(array('report_helper', 'map_helper')); $auth = report_helper::get_read_auth($args['website_id'], $args['password']); $reportOptions = iform_report_get_report_options($args, $auth); $r = '<div class="ui-helper-clearfix">'; $reportOptions['geoserverLayer'] = $args['geoserver_layer']; $reportOptions['geoserverLayerStyle'] = $args['geoserver_layer_style']; $reportOptions['cqlTemplate'] = $args['cql_template']; $reportOptions['clickable'] = $args['click_on_map_mode'] != 'none'; $reportOptions['clickableLayersOutputDiv'] = $args['click_on_map_div']; if (!empty($args['click_on_map_columns'])) { $reportOptions['clickableLayersOutputColumns'] = helper_base::explode_lines_key_value_pairs($args['click_on_map_columns']); } if ($args['click_on_map_mode'] != 'none') { $reportOptions['clickableLayersOutputMode'] = $args['click_on_map_mode']; } // Use the proxy module if enabled, to get round limitations in URL length for // filtered WMS requests. if (defined('DRUPAL_BOOTSTRAP_CONFIGURATION') && module_exists('iform_proxy')) { global $base_url; $reportOptions['proxy'] = $base_url . '/?q=' . variable_get('iform_proxy_path', 'proxy') . '&url='; } $r .= '<br/>' . report_helper::report_map($reportOptions); $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); // This is used for drawing, so need an editlayer, but not used for input $options['editLayer'] = true; $options['editLayerInSwitcher'] = true; $options['clickForSpatialRef'] = false; if ($args['layer_picker'] != 'none') { $picker = array('id' => 'map-layer-picker', 'includeIcons' => false, 'includeSwitchers' => true, 'includeHiddenLayers' => true); if ($args['layer_picker'] == 'before') { $r .= map_helper::layer_list($picker); } // as we have a layer picker, we can drop the layerSwitcher from the OL map. if (array_search('layerSwitcher', $options['standardControls']) !== false) { unset($options['standardControls'][array_search('layerSwitcher', $options['standardControls'])]); } } if ($args['legend'] != 'none') { $legend = array('id' => 'map-legend', 'includeIcons' => true, 'includeSwitchers' => false, 'includeHiddenLayers' => false); if ($args['legend'] == 'before') { $r .= map_helper::layer_list($legend); } } if (isset($args['map_toolbar_pos'])) { $options['toolbarDiv'] = $args['map_toolbar_pos']; } $r .= map_helper::map_panel($options, $olOptions); if ($args['layer_picker'] == 'after') { $r .= map_helper::layer_list($picker); } if ($args['legend'] == 'after') { $r .= map_helper::layer_list($legend); } $r .= '</div>'; return $r; }
/** * Return the generated form output. * @return Form HTML. */ public static function get_form($args) { iform_load_helpers(array('map_helper', 'data_entry_helper')); global $user; $readAuth = map_helper::get_read_auth($args['website_id'], $args['password']); // setup the map options $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); if (!$args['show_all_species']) { if (isset($args['taxon_identifier']) && !empty($args['taxon_identifier'])) { // This page is for a predefined species map $taxonIdentifier = $args['taxon_identifier']; } else { if (isset($_GET['taxon'])) { $taxonIdentifier = $_GET['taxon']; } else { return lang::get("The distribution map cannot be displayed without a taxon identifier"); } } if ($args['external_key'] == true) { if (empty($args['taxon_list_id'])) { return lang::get('This form is configured with the Distribution Layer - External Key option ticked, but no species list has been configured to ' . 'lookup the external keys against.'); } // the taxon identifier is an external key, so we need to translate to a meaning ID. $fetchOpts = array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('view' => 'detail', 'external_key' => $taxonIdentifier, 'taxon_list_id' => $args['taxon_list_id'], 'preferred' => true)); $prefRecords = data_entry_helper::get_population_data($fetchOpts); // We might have multiple records back, e.g. if there are several photos, but we should have a unique meaning id. $meaningId = 0; foreach ($prefRecords as $prefRecord) { if ($meaningId != 0 && $meaningId != $prefRecord['taxon_meaning_id']) { // bomb out, as we don't know which taxon to display return lang::get("The taxon identifier cannot be used to identify a unique taxon."); } $meaningId = $prefRecord['taxon_meaning_id']; } if ($meaningId == 0) { return lang::get("The taxon identified by the taxon identifier cannot be found."); } $meaningId = $prefRecords[0]['taxon_meaning_id']; } else { // the taxon identifier is the meaning ID. $meaningId = $taxonIdentifier; } // We still need to fetch the species record, to get its common name $fetchOpts = array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('view' => 'detail', 'language_iso' => iform_lang_iso_639_2(hostsite_get_user_field('language')), 'taxon_meaning_id' => $meaningId)); $taxonRecords = data_entry_helper::get_population_data($fetchOpts); } $url = map_helper::$geoserver_url . 'wms'; // Get the style if there is one selected $style = $args["wms_style"] ? ", styles: '" . $args["wms_style"] . "'" : ''; map_helper::$onload_javascript .= "\n var filter='website_id=" . $args['website_id'] . "';"; if ($args['show_all_species']) { $layerTitle = lang::get('All species occurrences'); } else { $layerTitle = str_replace('{species}', $taxonRecords[0]['taxon'], $args['layer_title']); map_helper::$onload_javascript .= "\n filter += ' AND taxon_meaning_id={$meaningId}';\n"; } if (!empty($args['cql_filter'])) { map_helper::$onload_javascript .= "\n filter += ' AND(" . str_replace("'", "\\'", $args['cql_filter']) . ")';\n"; } $layerTitle = str_replace("'", "\\'", $layerTitle); map_helper::$onload_javascript .= "\n var distLayer = new OpenLayers.Layer.WMS(\r\n '" . $layerTitle . "',\r\n '{$url}',\r\n {layers: '" . $args["wms_feature_type"] . "', transparent: true, CQL_FILTER: filter {$style}},\r\n {isBaseLayer: false, sphericalMercator: true, singleTile: true}\r\n );\n"; $options['layers'][] = 'distLayer'; if (isset($args['click_on_occurrences_mode']) && $args['click_on_occurrences_mode'] != 'none') { $options['clickableLayersOutputMode'] = $args['click_on_occurrences_mode']; $options['clickableLayersOutputDiv'] = 'getinfo-output'; $options['clickableLayers'][] = 'distLayer'; if (!empty($args['click_columns'])) { // convert the input column list argument to a structured array to pass to the map $inputarr = explode("\r\n", $args['click_columns']); $outputarr = array(); foreach ($inputarr as $coldef) { $coldef = explode('=', $coldef); $outputarr[$coldef[0]] = $coldef[1]; } $options['clickableLayersOutputColumns'] = $outputarr; } } // This is not a map used for input $options['editLayer'] = false; // if in Drupal, and IForm proxy is installed, then use this path as OpenLayers proxy if (defined('DRUPAL_BOOTSTRAP_CONFIGURATION') && module_exists('iform_proxy')) { global $base_url; $options['proxy'] = $base_url . '?q=' . variable_get('iform_proxy_path', 'proxy') . '&url='; } // output a legend if (isset($args['include_layer_list_types'])) { $layerTypes = explode(',', $args['include_layer_list_types']); } else { $layerTypes = array('base', 'overlay'); } $r = ''; if (!isset($args['include_layer_list']) || $args['include_layer_list']) { $r .= map_helper::layer_list(array('includeSwitchers' => isset($args['include_layer_list_switchers']) ? $args['include_layer_list_switchers'] : true, 'includeHiddenLayers' => true, 'layerTypes' => $layerTypes)); } // output a map $r .= map_helper::map_panel($options, $olOptions); // add an empty div for the output of getinfo requests if (isset($args['click_on_occurrences_mode']) && $args['click_on_occurrences_mode'] == 'div') { $r .= '<div id="getinfo-output"></div>'; } // Set up a page refresh for dynamic update of the map at set intervals if (!empty($args['refresh_timer']) && $args['refresh_timer'] !== 0 && is_numeric($args['refresh_timer'])) { // is_int prevents injection if (isset($args['load_on_refresh']) && !empty($args['load_on_refresh'])) { map_helper::$javascript .= "setTimeout('window.location=\"" . $args['load_on_refresh'] . "\";', " . $args['refresh_timer'] . "*1000 );\n"; } else { map_helper::$javascript .= "setTimeout('window.location.reload( false );', " . $args['refresh_timer'] . "*1000 );\n"; } } return $r; }
/** * Return the generated form output. * @return Form HTML. * @todo: Implement this method */ public static function get_form($args) { global $user; $lang = isset($user) ? iform_lang_iso_639_2($user->lang) : 'eng'; require_once dirname(dirname(__FILE__)) . '/map_helper.php'; $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']); $r = ''; // setup the map options $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); if (array_key_exists('table', $_GET) && $_GET['table'] == 'sample') { // Use a cUrl request to get the data from Indicia which contains the value we need to filter against // Read the record that was just posted. $fetchOpts = array('dataSource' => 'reports_for_prebuilt_forms/my_dot_map/occurrences_list', 'mode' => 'report', 'readAuth' => $readAuth, 'extraParams' => array('sample_id' => $_GET['id'], 'language' => $lang)); // @todo Error handling on the response $occurrence = data_entry_helper::get_report_data($fetchOpts); self::prepare_layer_titles($args, $occurrence); // Add the 3 distribution layers if present. Reverse the order so 1st layer is topmost $layerName = self::build_distribution_layer(3, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } $layerName = self::build_distribution_layer(2, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } $layerName = self::build_distribution_layer(1, $args, $occurrence); if ($layerName) { $options['layers'][] = $layerName; } if ($layerName) { $options['layers'][] = $layerName; } // This is not a map used for input $options['editLayer'] = false; if ($args['hide_grid'] == false) { // Now output a grid of the occurrences that were just saved. $r .= "<table class=\"submission\"><thead><tr><th>" . lang::get('Species') . "</th><th>" . lang::get('Latin Name') . "</th><th>" . lang::get('Date') . "</th><th>" . lang::get('Spatial Ref') . "</th></tr></thead>\n"; $r .= "<tbody>\n"; foreach ($occurrence as $record) { $r .= '<tr class="biota"><td>' . $record['lt4_taxon'] . '</td><td class="binomial"><em>' . $record['lt7_taxon'] . '</em></td><td>' . $record['lt0_date_start'] . '</td><td>' . $record['lt0_entered_sref'] . "</td></tr>\n"; } $r .= "</tbody></table>\n"; } } $r .= '<div id="mapandlegend">'; $r .= map_helper::layer_list(array('id' => 'legend', 'includeSwitchers' => false, 'includeHiddenLayers' => false, 'includeIcons' => true, 'layerTypes' => array('overlay'))); $r .= map_helper::map_panel($options, $olOptions); $r .= '</div>'; return $r; }
/** * Draw Map section of the page. * @return string The output map panel. * * @package Client * @subpackage PrebuiltForms */ protected static function get_control_map($auth, $args, $tabalias, $options) { iform_load_helpers(array('map_helper', 'data_entry_helper')); global $user; // setup the map options $options = iform_map_get_map_options($args, $auth['read']); if ($args['interface'] !== 'one_page') { $options['tabDiv'] = $tabalias; } $olOptions = iform_map_get_ol_options($args); $url = map_helper::$geoserver_url . 'wms'; // Get the style if there is one selected $style = $args["wms_style"] ? ", styles: '" . $args["wms_style"] . "'" : ''; map_helper::$onload_javascript .= "\n var filter='website_id=" . $args['website_id'] . "';"; $layerTitle = str_replace('{species}', self::get_best_name(), $args['layer_title']); map_helper::$onload_javascript .= "\n filter += ' AND taxon_meaning_id=" . self::$taxon_meaning_id . "';\n"; if ($args['cql_filter']) { map_helper::$onload_javascript .= "\n filter += ' AND(" . str_replace("'", "\\'", $args['cql_filter']) . ")';\n"; } $layerTitle = str_replace("'", "\\'", $layerTitle); map_helper::$onload_javascript .= "\n var distLayer = new OpenLayers.Layer.WMS(\n '" . $layerTitle . "',\n '{$url}',\n {layers: '" . $args["wms_feature_type"] . "', transparent: true, CQL_FILTER: filter {$style}},\n {isBaseLayer: false, sphericalMercator: true, singleTile: true}\n );\n"; $options['layers'][] = 'distLayer'; // This is not a map used for input $options['editLayer'] = false; // if in Drupal, and IForm proxy is installed, then use this path as OpenLayers proxy if (defined('DRUPAL_BOOTSTRAP_CONFIGURATION') && module_exists('iform_proxy')) { global $base_url; $options['proxy'] = $base_url . '?q=' . variable_get('iform_proxy_path', 'proxy') . '&url='; } // output a legend if (isset($args['include_layer_list_types'])) { $layerTypes = explode(',', $args['include_layer_list_types']); } else { $layerTypes = array('base', 'overlay'); } $r = '<div class="detail-panel" id="detail-panel-map"><h3>' . lang::get('Map') . '</h3>'; //Legend options set by the user if (!isset($args['include_layer_list']) || $args['include_layer_list']) { $r .= map_helper::layer_list(array('includeSwitchers' => isset($args['include_layer_list_switchers']) ? $args['include_layer_list_switchers'] : true, 'includeHiddenLayers' => true, 'layerTypes' => $layerTypes)); } $r .= map_helper::map_panel($options, $olOptions); $r .= '</div>'; // Set up a page refresh for dynamic update of the map at set intervals if ($args['refresh_timer'] !== 0 && is_numeric($args['refresh_timer'])) { // is_int prevents injection if (isset($args['load_on_refresh']) && !empty($args['load_on_refresh'])) { map_helper::$javascript .= "setTimeout('window.location=\"" . $args['load_on_refresh'] . "\";', " . $args['refresh_timer'] . "*1000 );\n"; } else { map_helper::$javascript .= "setTimeout('window.location.reload( false );', " . $args['refresh_timer'] . "*1000 );\n"; } } return $r; }
/** * Return the generated form output. * @param array $args List of parameter values passed through to the form depending on how the form has been configured. * This array always contains a value for language. * @param object $node The Drupal node object. * @param array $response When this form is reloading after saving a submission, contains the response from the service call. * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data). * @return Form HTML. * @todo: Implement this method */ public static function get_form($args, $node, $response = null) { iform_load_helpers(array('report_helper', 'map_helper')); $conn = iform_get_connection_details($node); $readAuth = report_helper::get_read_auth($conn['website_id'], $conn['password']); $r = '<div id="leftcol">'; $reportOptions = iform_report_get_report_options($args, $readAuth); iform_report_apply_explore_user_own_preferences($reportOptions); $reportOptions = array_merge(array('rowId' => 'external_key', 'columns' => array(), 'callback' => 'grid_load', 'rememberParamsReportGroup' => 'explore', 'paramsFormButtonCaption' => lang::get('Filter')), $reportOptions); $reportOptions['rowId'] = 'external_key'; $imgPath = empty(report_helper::$images_path) ? report_helper::relative_client_helper_path() . "../media/images/" : report_helper::$images_path; $reportOptions['columns'][] = array('actions' => array(array('img' => "{$imgPath}/add.png", 'caption' => 'Click to add this species to the map'))); $r .= report_helper::report_grid($reportOptions); $r .= '</div>'; $args['indicia_species_layer_slds'] = report_helper::explode_lines($args['indicia_species_layer_slds']); $r .= '<div id="rightcol">'; $r .= '<div id="layerbox">'; $r .= '<p id="instruct">' . lang::get('Click on the + buttons in the grid to add species layers to the map. You can add up to {1} layers at a time.', count($args['indicia_species_layer_slds'])); $r .= '<p id="instruct2" style="display: none">' . lang::get('Use the - buttons to permanently remove layers, or untick the box in the legend to temporarily hide them.'); $mapOptions = iform_map_get_map_options($args, $readAuth); $mapOptions['clickForSpatialRef'] = false; $olOptions = iform_map_get_ol_options($args, $readAuth); $r .= map_helper::layer_list(array('layerTypes' => array('overlay'), 'includeSwitchers' => true, 'includeHiddenLayers' => true)); $r .= '</div>'; $r .= map_helper::map_panel($mapOptions, $olOptions); $r .= '</div>'; $websiteIds = iform_get_allowed_website_ids($readAuth); if (!empty($args['indicia_species_layer_feature_type']) && !empty(report_helper::$geoserver_url)) { $training = function_exists('hostsite_get_user_field') && hostsite_get_user_field('training') ? 't' : 'f'; $cql = 'website_id IN (' . implode(',', $websiteIds) . ') AND ' . $args['indicia_species_layer_filter_field'] . "='{filterValue}' AND record_status NOT IN ('R', 'I', 'T') AND training='{$training}'"; if (isset($_POST[$reportOptions['reportGroup'] . '-quality'])) { $quality = $_POST[$reportOptions['reportGroup'] . '-quality']; } else { $quality = $reportOptions['extraParams']['quality']; } // logic here must match the quality_check function logic on the database. switch ($quality) { case 'V': $cql .= " AND record_status='V'"; break; case 'C': $cql .= " AND (record_status='V' OR certainty='C')"; break; case 'L': $cql .= " AND (record_status='V' OR ((certainty <> 'U' OR certainty IS NULL) AND record_status <> 'D'))"; break; case '!D': $cql .= " AND record_status<>'D'"; break; case '!R': // nothing to add - rejects are always excluded } report_helper::$javascript .= "indiciaData.indiciaSpeciesLayer = {\n" . ' "title":"' . lang::get('{1}') . "\",\n" . ' "myRecords":"' . lang::get('my records') . "\",\n" . ' "userId":"' . hostsite_get_user_field('indicia_user_id') . "\",\n" . ' "featureType":"' . $args['indicia_species_layer_feature_type'] . "\",\n" . ' "wmsUrl":"' . data_entry_helper::$geoserver_url . "wms\",\n" . " \"cqlFilter\":\"{$cql}\",\n" . " \"filterField\":\"taxon_meaning_id\",\n" . ' "slds":' . json_encode($args['indicia_species_layer_slds']) . "\n" . "};\n"; } return $r; }