Visualize GIS data with OpenStreetMap as a base layer

This commit is contained in:
Madhura Jayaratne 2011-06-12 20:04:23 +05:30
parent 7fca97fdde
commit 5f09cf550f
14 changed files with 416 additions and 12 deletions

View File

@ -62,6 +62,35 @@ function zoomAndPan() {
* Displaying tooltips for GIS objects.
*/
$(document).ready(function() {
var $placeholder = $('#placeholder');
var $openlayersmap = $('#openlayersmap');
if ($('#choice').prop('checked') != true) {
$openlayersmap.hide();
} else {
$placeholder.hide();
}
var cssObj = {
'border' : '1px solid #aaa',
'width' : $placeholder.width(),
'height' : $placeholder.height(),
'float' : 'right'
};
$openlayersmap.css(cssObj);
drawOpenLayers();
$('.choice').show();
$('#choice').bind('click', function() {
if ($(this).prop('checked') == false) {
$placeholder.show();
$openlayersmap.hide();
} else {
$placeholder.hide();
$openlayersmap.show();
}
});
$('#placeholder').svg({
onLoad: function(svg_ref) {
svg = svg_ref;

View File

@ -95,8 +95,14 @@ abstract class PMA_GIS_Geometry
// Extract cordinates of the point
$cordinates = explode(" ", $point);
$x = ($cordinates[0] - $scale_data['x']) * $scale_data['scale'];
$y = $scale_data['height'] - ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
if ($scale_data != null) {
$x = ($cordinates[0] - $scale_data['x']) * $scale_data['scale'];
$y = $scale_data['height'] - ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
} else {
$x = $cordinates[0];
$y = $cordinates[1];
}
if (! $linear) {
$points_arr[] = array($x, $y);
} else {

View File

@ -164,6 +164,35 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS GEOMETRYCOLLECTION object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS GEOMETRYCOLLECTION object
* @param string $color Color for the GIS GEOMETRYCOLLECTION object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $color)
{
$row = '';
// Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
$goem_col = substr($spatial, 19, (strlen($spatial) - 20));
// Split the geometry collection object to get its constituents.
$sub_parts = $this->_explodeGeomCol($goem_col);
foreach ($sub_parts as $sub_part) {
$type_pos = stripos($sub_part, '(');
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
$row .= $gis_obj->prepareRowAsOl($sub_part, $srid, $label, $color);
}
return $row;
}
/**
* Split the GEOMETRYCOLLECTION object and get its constituents.
*

View File

@ -152,5 +152,41 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS LINESTRING object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS LINESTRING object
* @param string $line_color Color for the GIS LINESTRING object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $line_color)
{
$style_options = array(
'strokeColor' => $line_color,
'strokeWidth' => 2,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'LINESTRING(' and trailing ')'
$linesrting = substr($spatial, 11, (strlen($spatial) - 12));
$points_arr = $this->extractPoints($linesrting, null);
$row = 'new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')';
return 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
. 'new OpenLayers.Geometry.LineString(' . $row . '), null, '
. json_encode($style_options) . '));';
}
}
?>

View File

@ -177,5 +177,46 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS MULTILINESTRING object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS MULTILINESTRING object
* @param string $line_color Color for the GIS MULTILINESTRING object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $line_color)
{
$style_options = array(
'strokeColor' => $line_color,
'strokeWidth' => 2,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'MULTILINESTRING((' and trailing '))'
$multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
// Seperate each linestring
$linestirngs = explode("),(", $multilinestirng);
$row = 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
. 'new OpenLayers.Geometry.MultiLineString(new Array(';
foreach ($linestirngs as $linestring) {
$points_arr = $this->extractPoints($linestring, null);
$row .= 'new OpenLayers.Geometry.LineString(new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')), null, ' . json_encode($style_options) . '));';
return $row;
}
}
?>

View File

@ -141,5 +141,43 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS MULTIPOINT object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS MULTIPOINT object
* @param string $point_color Color for the GIS MULTIPOINT object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $point_color)
{
$style_options = array(
'pointRadius' => 3,
'fillColor' => '#ffffff',
'strokeColor' => $point_color,
'strokeWidth' => 2,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'MULTIPOINT(' and trailing ')'
$multipoint = substr($spatial, 11, (strlen($spatial) - 12));
$points_arr = $this->extractPoints($multipoint, null);
$row = 'new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')';
return 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
. 'new OpenLayers.Geometry.MultiPoint(' . $row . '), null, '
. json_encode($style_options) . '));';
}
}
?>

View File

@ -222,6 +222,69 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS MULTIPOLYGON object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS MULTIPOLYGON object
* @param string $fill_color Color for the GIS MULTIPOLYGON object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $fill_color)
{
$style_options = array(
'strokeColor' => '#000000',
'strokeWidth' => 0.5,
'fillColor' => $fill_color,
'fillOpacity' => 0.8,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
$multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
// Seperate each polygon
$polygons = explode(")),((", $multipolygon);
$row = 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
. 'new OpenLayers.Geometry.MultiPolygon(new Array(';
foreach ($polygons as $polygon) {
$row .= 'new OpenLayers.Geometry.Polygon(new Array(';
// If the polygon doesnt have an inner polygon
if (strpos($polygon, "),(") === false) {
$points_arr = $this->extractPoints($polygon, null);
$row .= 'new OpenLayers.Geometry.LinearRing(new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= '))';
} else {
// Seperate outer and inner polygons
$parts = explode("),(", $polygon);
foreach ($parts as $ring) {
$points_arr = $this->extractPoints($ring, null);
$row .= 'new OpenLayers.Geometry.LinearRing(new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')), ';
}
$row = substr($row, 0, strlen($row) - 2);
}
$row .= ')), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')), null, ' . json_encode($style_options) . '));';
return $row;
}
/**
* Draws a ring of the polygon using SVG path element.
*

View File

@ -134,5 +134,36 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS POINT object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS POINT object
* @param string $point_color Color for the GIS POINT object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $point_color)
{
$style_options = array(
'pointRadius' => 3,
'fillColor' => '#ffffff',
'strokeColor' => $point_color,
'strokeWidth' => 2,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'POINT(' and trailing ')'
$point = substr($spatial, 6, (strlen($spatial) - 7));
$points_arr = $this->extractPoints($point, null);
return 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector(('
. 'new OpenLayers.Geometry.Point(' . $points_arr[0][0] . ', ' . $points_arr[0][1] . ')'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject())),'
. ' null, ' . json_encode($style_options) . '));';
}
}
?>

View File

@ -165,7 +165,6 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
*/
public function prepareRowAsSvg($spatial, $label, $fill_color, $scale_data)
{
$group_name = 'g';
$polygon_options = array(
'name' => $label,
'id' => $label . rand(),
@ -206,6 +205,61 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
return $row;
}
/**
* Prepares the code related to a row in the GIS dataset to visualize it with OpenLayers.
*
* @param string $spatial GIS POLYGON object
* @param int $srid Spatial reference ID
* @param string $label Label for the GIS POLYGON object
* @param string $fill_color Color for the GIS POLYGON object
*
* @return the code related to a row in the GIS dataset
*/
public function prepareRowAsOl($spatial, $srid, $label, $fill_color)
{
$style_options = array(
'strokeColor' => '#000000',
'strokeWidth' => 0.5,
'fillColor' => $fill_color,
'fillOpacity' => 0.8,
);
if ($srid == 0) {
$srid = 4326;
}
// Trim to remove leading 'POLYGON((' and trailing '))'
$polygon = substr($spatial, 9, (strlen($spatial) - 11));
$row = 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
. 'new OpenLayers.Geometry.Polygon(new Array(';
// If the polygon doesnt have an inner polygon
if (strpos($polygon, "),(") === false) {
$points_arr = $this->extractPoints($polygon, null);
$row .= 'new OpenLayers.Geometry.LinearRing(new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= '))';
} else {
// Seperate outer and inner polygons
$parts = explode("),(", $polygon);
foreach ($parts as $ring) {
$points_arr = $this->extractPoints($ring, null);
$row .= 'new OpenLayers.Geometry.LinearRing(new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:' . $srid . '"), map.getProjectionObject()), ';
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')), ';
}
$row = substr($row, 0, strlen($row) - 2);
}
$row .= ')), null, ' . json_encode($style_options) . '));';
return $row;
}
/**
* Draws a ring of the polygon using SVG path element.
*

View File

@ -243,6 +243,18 @@ class PMA_GIS_Visualization
imagedestroy($img);
}
/**
* Get the code for visualization with OpenLayers.
*
* @return the code for visualization with OpenLayers
*/
public function asOl()
{
$this->init();
$output = $this->_prepareDataSet($this->_data, 0, null, 'ol', '');
return $output;
}
/**
* Saves as a PDF to a file.
*
@ -393,6 +405,11 @@ class PMA_GIS_Visualization
$row[$this->_settings['spatialColumn']], $label,
$this->_settings['colors'][$index], $scale_data, $results
);
} elseif ($format == 'ol') {
$results .= $gis_obj->prepareRowAsOl(
$row[$this->_settings['spatialColumn']], $row['srid'],
$label, $this->_settings['colors'][$index]
);
}
$color_number++;
}

View File

@ -51,8 +51,11 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
$is_spatial_alias = false;
foreach ($analyzed_query[0]['select_expr'] as $select) {
if ($select['alias'] == $visualizationSettings['spatialColumn']) {
$modified_query .= 'ASTEXT(' . sanitize($select) . ') AS `'
. $select['alias'] . '` ';
$sanitized = sanitize($select);
$modified_query .= 'ASTEXT(' . $sanitized . ') AS `'
. $select['alias'] . '`, ';
// Get the SRID
$modified_query .= 'SRID(' . $sanitized . ') AS `srid` ';
$is_spatial_alias = true;
break;
}
@ -61,8 +64,11 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
if (! $is_spatial_alias) {
foreach ($analyzed_query[0]['select_expr'] as $select) {
if ($select['column'] == $visualizationSettings['spatialColumn']) {
$modified_query .= 'ASTEXT(' . sanitize($select)
. ') AS `' . $select['column'] . '` ';
$sanitized = sanitize($select);
$modified_query .= 'ASTEXT(' . $sanitized
. ') AS `' . $select['column'] . '`, ';
// Get the SRID
$modified_query .= 'SRID(' . $sanitized . ') AS `srid` ';
}
}
}
@ -75,7 +81,10 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
// Wrap the spatial column with 'ASTEXT()' function and add it
$modified_query .= 'ASTEXT(`' . $visualizationSettings['spatialColumn']
. '`) AS `' . $visualizationSettings['spatialColumn'] . '` ';
. '`) AS `' . $visualizationSettings['spatialColumn'] . '`, ';
// Get the SRID
$modified_query .= 'SRID(`' . $visualizationSettings['spatialColumn'] . '`) AS `srid` ';
}
// Append the rest of the query
@ -131,6 +140,8 @@ function PMA_GIS_visualization_results($data, &$visualizationSettings, $format)
return $visualization->asSvg();
} elseif ($format == 'png') {
return $visualization->asPng();
} elseif ($format == 'ol') {
return $visualization->asOl();
}
}
}

View File

@ -98,14 +98,14 @@ $visualization = PMA_GIS_visualization_results($data, $visualizationSettings, $f
<?php echo PMA_generate_common_hidden_inputs($url_params); ?>
<fieldset>
<legend><?php echo __('Display GIS Visualization'); ?></legend>
<div id="placeholder" style="width:<?php echo($visualizationSettings['width']); ?>px;height:<?php echo($visualizationSettings['height']); ?>px;border:1px solid #484;float:right">
<div id="placeholder" style="width:<?php echo($visualizationSettings['width']); ?>px;height:<?php echo($visualizationSettings['height']); ?>px;border:1px solid #aaa;float:right">
<?php echo $visualization; ?>
</div>
<div id="openlayersmap"></div>
<?php
if ($format == 'svg') {
?>
<script language="javascript" type="text/javascript">
$(document).ready(function(){
var $placeholder = $('#placeholder');
// add zoom out button
@ -116,7 +116,38 @@ if ($format == 'svg') {
$('<img class="button" id="up_arrow" src="<?php echo($GLOBALS['pmaThemeImage']); ?>arrow-up.gif">').appendTo($placeholder);
$('<img class="button" id="down_arrow" src="<?php echo($GLOBALS['pmaThemeImage']); ?>arrow-down.gif">').appendTo($placeholder);
});
</script>
<script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script language="javascript" type="text/javascript">
function drawOpenLayers() {
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),
restrictedExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)
};
var map = new OpenLayers.Map('openlayersmap', options);
// create OSM layer
var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
var layerOsmarender = new OpenLayers.Layer.OSM.Osmarender("Osmarender");
var layerCycleMap = new OpenLayers.Layer.OSM.CycleMap("CycleMap");
map.addLayers([layerMapnik, layerOsmarender, layerCycleMap]);
// create a vector layer
var vectorLayer = new OpenLayers.Layer.Vector("Data");
<?php echo (PMA_GIS_visualization_results($data, $visualizationSettings, 'ol')); ?>
map.addLayer(vectorLayer);
map.setCenter(new OpenLayers.LonLat(0, 0), 2);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
}
</script>
<?php
}
@ -132,7 +163,7 @@ if ($format == 'svg') {
<td><input type="text" name="visualizationSettings[height]" id="height" value="<?php echo (isset($visualizationSettings['height']) ? htmlspecialchars($visualizationSettings['height']) : ''); ?>" /></td>
</tr>
<tr><td><label for="labelColumn"><?php echo __("Label Column"); ?></label></td>
<tr><td><label for="labelColumn"><?php echo __("Label column"); ?></label></td>
<td><select name="visualizationSettings[labelColumn]" id="labelColumn">
<?php
foreach ($labelCandidates as $labelCandidate) {
@ -146,7 +177,7 @@ if ($format == 'svg') {
</select></td>
</tr>
<tr><td><label for="spatial Column"><?php echo __("Spatial Column"); ?></label></td>
<tr><td><label for="spatial Column"><?php echo __("Spatial column"); ?></label></td>
<td><select name="visualizationSettings[spatialColumn]" id="spatialColumn">
<?php
foreach ($spatialCandidates as $spatialCandidate) {
@ -159,6 +190,16 @@ if ($format == 'svg') {
?>
</select></td>
</tr>
<tr><td class="choice">
<input type="checkbox" name="visualizationSettings[choice]" id="choice" value="useBaseLayer"
<?php
if (isset($visualizationSettings['choice'])) {
echo(' checked="checked"');
}
?>
/>
<label for="choice"><?php echo __("Use base layer"); ?></label>
</td></tr>
<tr><td></td>
<td class="button"><input type="submit" name="displayVisualization" value="<?php echo __('Redraw'); ?>" /></td>
</tr>

View File

@ -1825,6 +1825,10 @@ fieldset .disabled-field td {
text-align: <?php echo $right; ?>;
}
.gis_table .choice {
display:none;
}
.CodeMirror {
line-height: 1em;
font-family: monospace;

View File

@ -2171,6 +2171,10 @@ fieldset .disabled-field td {
text-align: <?php echo $right; ?>;
}
.gis_table .choice {
display: none;
}
.CodeMirror {
line-height: 1em;
font-family: monospace;