diff --git a/report_helper.php b/report_helper.php index bffe19589..73777ddaf 100644 --- a/report_helper.php +++ b/report_helper.php @@ -1765,65 +1765,91 @@ public static function report_map($options) { 'dataSourceLoRes'=>'', ), $options); $options = self::get_report_grid_options($options); - // keep track of the columns in the report output which we need to draw the layer + + // Keep track of the columns in the report output which we need to draw the layer and popups. $colsToInclude=array(); + if (empty($options['geoserverLayer'])) { - if ($options['ajax']) - // just load the report structure, as Ajax will load content later + // We are doing vector mapping from an Indicia report. + + if ($options['ajax']) { + // Just load the report structure, as Ajax will load content later. $options['extraParams']['limit']=0; + } + self::request_report($response, $options, $currentParamValues, false, ''); - if (isset($response['error'])) return $response['error']; + if (isset($response['error'])) { + // Return immediately on error. + return $response['error']; + } $r = self::params_form_if_required($response, $options, $currentParamValues); - // return the params form, if that is all that is being requested, or the parameters are not complete. - if ($options['paramsOnly'] || !isset($response['records'])) + if ($options['paramsOnly'] || !isset($response['records'])) { + // Return the params form, if that is all that is being requested, or the parameters are not complete. return $r; + } $records = $response['records']; - // find the geom column + + // Find the geom column. foreach($response['columns'] as $col=>$cfg) { if (isset($cfg['mappable']) && $cfg['mappable']=='true') { $wktCol = $col; break; } } - if (!isset($wktCol)) + if (!isset($wktCol)) { $r .= "
".lang::get("The report's configuration does not output any mappable data")."
"; - } else { - // using geoserver, so we just need to know the param values. + } + else { + // Always include geom in output even if marked as not visible in report. + $colsToInclude[$wktCol]=''; + } + + if (isset($options['rowId'])) { + // Always include Id in output even if marked as not visible in report. + $colsToInclude[$options['rowId']] = ''; + } + + } + else { + // We are doing WMS mapping using geoserver, so we just need to know the param values. $currentParamValues = self::get_report_grid_current_param_values($options); $response = self::get_report_data($options, self::array_to_query_string($currentParamValues, true).'&wantRecords=0&wantParameters=1'); $r = self::get_report_grid_parameters_form($response, $options, $currentParamValues); } + if (isset($response['records']) || !isset($response['parameterRequest']) || - count(array_intersect_key($currentParamValues, $response['parameterRequest']))==count($response['parameterRequest'])) { + count(array_intersect_key($currentParamValues, $response['parameterRequest'])) == count($response['parameterRequest'])) { + // We are ready to draw the map. + if (empty($options['geoserverLayer'])) { - // we are doing vector reporting via indicia services - // first we need to build a style object which respects columns in the report output that define style settings for each vector. - // default features are blue and red if selected + // We are doing vector mapping from an Indicia report. + + // Build a default style object which is blue or red if selected. $defsettings = array( - 'fillColor'=> '#0000ff', - 'strokeColor'=> '#0000ff', - 'strokeWidth'=>empty($options['featureDoubleOutlineColour']) ? "\${getstrokewidth}" : 1, - 'fillOpacity'=>"\${getfillopacity}", - 'strokeOpacity'=>0.8, - 'pointRadius'=>"\${getpointradius}", - 'graphicZIndex'=>"\${getgraphiczindex}"); + 'fillColor' => '#0000ff', + 'strokeColor' => '#0000ff', + 'strokeWidth' => empty($options['featureDoubleOutlineColour']) ? "\${getstrokewidth}" : 1, + 'fillOpacity' => "\${getfillopacity}", + 'strokeOpacity' => 0.8, + 'pointRadius' => "\${getpointradius}", + 'graphicZIndex' => "\${getgraphiczindex}"); $selsettings = array_merge($defsettings, array( - 'fillColor'=> '#ff0000', - 'strokeColor'=> '#ff0000', - 'strokeOpacity'=>0.9) + 'fillColor' => '#ff0000', + 'strokeColor' => '#ff0000', + 'strokeOpacity' => 0.9) ); - $defStyleFns=array(); - $selStyleFns=array(); - // default fill opacity, more opaque if selected, and gets more transparent as you zoom in. + $defStyleFns = array(); + $selStyleFns = array(); + // Default fill opacity, more opaque if selected, and gets more transparent as you zoom in. $defStyleFns['fillOpacity'] = "getfillopacity: function(feature) { - return Math.max(0, 0.4-feature.layer.map.zoom/100); + return Math.max(0, 0.4 - feature.layer.map.zoom/100); }"; - // when selected, a little bit more opaque + // When selected, a little bit more opaque. $selStyleFns['fillOpacity'] = "getfillopacity: function(feature) { - return Math.max(0, 0.7-feature.layer.map.zoom/100); + return Math.max(0, 0.7 - feature.layer.map.zoom/100); }"; - // default fill opacity, more opaque if selected, and gets more transparent as you zoom in. + // Default radius based on precision of record but limited to maintain visibility when zoomed out. // Note that the number of map units only approximates a metre in web-mercator, accurate // near the equator but not near the poles. We use a very crude adjustment if necessary // which works well around the UK's latitude. @@ -1834,68 +1860,97 @@ public static function report_map($options) { } return Math.max(5, units / (feature.layer.map.getResolution())); }"; - // default z index, smaller objects on top + // Default z index, smaller objects on top. $defStyleFns['graphicZIndex'] = "getgraphiczindex: function(feature) { - return Math.round(feature.geometry.getBounds().left - feature.geometry.getBounds().right)+100000; + return Math.round(feature.geometry.getBounds().left - feature.geometry.getBounds().right) + 100000; }"; - // when selected, move objects upwards + // When selected, move objects upwards. $selStyleFns['graphicZIndex'] = "getgraphiczindex: function(feature) { - return Math.round(feature.geometry.getBounds().left - feature.geometry.getBounds().right)+200000; + return Math.round(feature.geometry.getBounds().left - feature.geometry.getBounds().right) + 200000; }"; - foreach($response['columns'] as $col=>$def) { + + // Override the default style object using columns in the report output that define style settings. + foreach($response['columns'] as $col => $def) { if (!empty($def['feature_style'])) { - if ($def['feature_style']==='fillOpacity') { - // replace the fill opacity functions to use a column value, with the same +0.3 change - // when selected + // Found a column that defines a style setting. + + if ($def['feature_style'] === 'fillOpacity') { + // Replace the fill opacity functions to use a column value. $defStyleFns['fillOpacity'] = "getfillopacity: function(feature) { - return Math.max(0, feature.attributes.$col-feature.layer.map.zoom/100); + return Math.max(0, feature.attributes.$col - feature.layer.map.zoom/100); }"; + // When selected, a little bit more opaque. $selStyleFns['fillOpacity'] = "getfillopacity: function(feature) { - return Math.max(0, feature.attributes.$col-feature.layer.map.zoom/100+0.3); + return Math.max(0, feature.attributes.$col - feature.layer.map.zoom/100 + 0.3); }"; - } elseif ($def['feature_style']==='graphicZIndex') { - // replace the default z index with the column value, using an fn to add 1000 when selected + } + elseif ($def['feature_style'] === 'graphicZIndex') { + // Replace the default z index with the column value. + // ${} syntax is explained at http://docs.openlayers.org/library/feature_styling.html. $defsettings['graphicZIndex'] = '${'.$col.'}'; + // When selected, move objects upwards. $selStyleFns['graphicZIndex'] = "getgraphiczindex: function(feature) { - return feature.attributes.$col+1000; + return feature.attributes.$col + 1000; }"; $selsettings['graphicZIndex'] = '${getgraphiczindex}'; - } else { - // found a column that outputs data to input into a feature style parameter. ${} syntax is explained at http://docs.openlayers.org/library/feature_styling.html. + } + else { + // Found a column that outputs data to input into a feature style parameter. + // ${} syntax is explained at http://docs.openlayers.org/library/feature_styling.html. $defsettings[$def['feature_style']] = '${'.$col.'}'; - if ($def['feature_style']!=='strokeColor') + if ($def['feature_style'] !== 'strokeColor') { + // Override the style for selected items too except red stroke colour. $selsettings[$def['feature_style']] = '${'.$col.'}'; + } } + + // We need to include in output any columns involved in the feature style. + $colsToInclude[$col] = ''; } } - if ($options['displaySymbol']!=='vector') - $defsettings['graphicName']=$options['displaySymbol']; - // The following function uses the strokeWidth to pad out the squares which go too small when zooming the map out. Points - // always display the same size so are no problem. Also, no need if using a double outline. + + if ($options['displaySymbol'] !== 'vector') { + // Use a symbol marker on the map rather than vector. + $defsettings['graphicName'] = $options['displaySymbol']; + } + + // The following function uses the strokeWidth to pad out the squares which go too small when zooming the map + // out. Points always display the same size so are no problem. Also, no need if using a double outline. if (empty($options['featureDoubleOutlineColour'])) { $strokeWidthFn = "getstrokewidth: function(feature) { - var width=feature.geometry.getBounds().right - feature.geometry.getBounds().left, - strokeWidth=(width===0) ? 1 : %d - (width / feature.layer.map.getResolution()); - return (strokeWidth<%d) ? %d : strokeWidth; + var width = feature.geometry.getBounds().right - feature.geometry.getBounds().left, + strokeWidth = (width === 0) ? 1 : %d - (width / feature.layer.map.getResolution()); + return (strokeWidth < %d) ? %d : strokeWidth; }"; $defStyleFns['getStrokeWidth'] = sprintf($strokeWidthFn, 9, 2, 2); $selStyleFns['getStrokeWidth'] = sprintf($strokeWidthFn, 10, 3, 3); } + + // The style objects can also be overriden by column values as specified in the valueOutput option. if (isset($options['valueOutput'])) { foreach($options['valueOutput'] as $type => $outputdef) { $value = $outputdef['valueField']; - // we need this value in the output + // We need this value in the output. $colsToInclude[$value]=''; + if (preg_match('/{(?P