<?php
function geo_backend_type() {
static $backend;
if (!isset($backend)) {
switch ($GLOBALS['db_type']) {
case 'pgsql':
if (db_result(db_query("SELECT 1 FROM pg_catalog.pg_proc
WHERE proname = 'postgis_version'"))) {
$backend = 'postgis';
}
break;
case 'mysql':
case 'mysqli':
if (db_result(@db_query("SELECT AsText(GeomFromText('POINT(1 1)'))")) == 'POINT(1 1)') {
$backend = 'mysql_spatial';
}
}
}
return $backend;
}
function geo_supported_types() {
return array(
'point' => t('Point'),
'linestring' => t('Linestring'),
'polygon' => t('Polygon'),
);
}
function geo_wkt_from_point($lat, $lon) {
if (strlen($lat) || strlen($lon)) {
return 'POINT('. $lon .' '. $lat .')';
}
}
function geo_field_select($field) {
if (!$field) return;
$field = check_plain($field);
$alias = str_replace('.', '_', $field);
$alias = preg_replace('/_geo$/', '', $alias);
return " SRID($field) as {$alias}_srid,
AsBinary($field) AS {$alias}_wkb,
AsBinary(Envelope($field)) AS {$alias}_bbox,
AsBinary(Centroid($field)) AS $alias}_centroid";
}
function geo_query_operators($geo_type) {
return array(
'Equals' => t('Equals'),
'NOT Equals' => t('Does not equal'),
'Intersects' => t('Intersects'),
'NOT Intersects' => t('Does not intersect'),
'Within' => t('Within'),
'NOT Within' => t('Not within'),
);
}
function geo_query_functions($geo_type) {
$geo_type = strtolower($geo_type);
$functions = array( 'wkt' => 'wkt', 'wkb' => 'wkb' );
if ($geo_type == 'point') {
$functions['lat'] = 'lat';
$functions['lon'] = 'lon';
}
if ($geo_type == 'polygon' || $geo_type == 'linestring') {
$functions['area'] = 'area';
$functions['bbox'] = 'bbox';
$functions['perimeter'] = 'perimeter';
}
if ($geo_type == 'linestring') {
$functions['start'] = 'start';
$functions['end'] = 'end';
}
return $functions;
}
function geo_query_handlers($geo_type) {
return array(
'wkt' => t('Well Known Text'),
'wkb' => t('Well Known Binary'),
'svg' => t('SVG'),
'kml' => t('KML'),
'gml' => t('GML'),
);
}
function geo_query_area($field, $srid = null) {
return 'Area('. $field .')';
}
function geo_query_bbox($field, $srid = null) {
return 'Envelope('. $field .')';
}
function geo_query_centroid($field, $srid = null) {
return 'Centroid('. $field .')';
}
function geo_query_geo_type($field, $srid = null) {
return 'GeometryType('. $field .')';
}
function geo_query_end($field, $srid = null) {
return 'EndPoint('. $field .')';
}
function geo_query_lat($field, $srid = null) {
return 'Y('. $field .')';
}
function geo_query_lon($field, $srid = null) {
return 'X('. $field .')';
}
function geo_query_length($field, $srid = null) {
return 'Length('. $field .')';
}
function geo_query_perimeter($field, $srid = null) {
return 'Length(ConvexHull('. $field .')';
}
function geo_query_start($field, $srid = null) {
return 'StartPoint('. $field .')';
}
function geo_query_wkt($field, $srid = null) {
return 'asText('. $field .')';
}
function geo_query_wkb($field, $srid = null) {
return 'asBinary('. $field .')';
}
function geo_query_distance($field, $srid = null, $target) {
$target = "GeomFromText('POINT(". $target['lon'] .','. $target['lat'] .")')";
return 'Distance('. $field .', '. $target .')';
}
function geo_query_within($field, $srid = null, $target) {
return "Within($field, GeomFromText('". $target['wkt'] ."'))";
}
function geo_query_contains($field, $srid = null, $target) {
return "Within(GeomFromText('". $target['wkt'] ."'), $field)";
}
function geo_make_bbox($target, $limit) {
$x = $target['lon'];
$y = $target['lat'];
$offset_x = $limit / (GEO_DEGREE_M * cos($y));
$offset_y = $limit / GEO_DEGREE_M;
$offset_x = $limit / GEO_DEGREE_M; $offset_y = $limit / round(GEO_DEGREE_M * cos($x / 92215));
$bbox = array(
'points' => array(
array('lon' => $x - $offset_x, 'lat' => $y + $offset_y),
array('lon' => $x + $offset_x, 'lat' => $y + $offset_y),
array('lon' => $x + $offset_x, 'lat' => $y - $offset_y),
array('lon' => $x - $offset_x, 'lat' => $y - $offset_y),
array('lon' => $x - $offset_x, 'lat' => $y + $offset_y),
),
);
$wkt = '';
foreach ($bbox['points'] as $p) $wkt .= $p['lon'] .' '. $p['lat'] .', ';
$bbox['wkt'] = 'POLYGON(('. substr($wkt, 0, -2) .'))';
return $bbox;
}
function geo_geo_from_wkt($wkt, $srid = GEO_DEFAULT_SRID) {
return " GeomFromText('". $wkt ."') ";
}
function geo_rss_item($wkb) {
$data = geo_wkb_get_data($wkb, 'text');
return array(
'key' => 'georss:'. strtolower($data['type']),
'value' => $data['value'],
'namespace' => array('xmlns:georss' => 'http://www.georss.org/georss'),
);
}
function geo_wkt_validate($wkt, $geo_type = NULL, $srid = GEO_DEFAULT_SRID) {
$type = db_result(@db_query("SELECT GeometryType(GeomFromText('%s'))", $wkt));
if (empty($type)) {
return t('Unable to parse WKT.');
}
if ($geo_type && strtolower($geo_type) != strtolower($type)) {
return t('Wrong geometry type. Got %result, was expecting %type.', array('%result' => $type, '%type' => $geo_type));
}
return TRUE;
}