Example #1
0
 /**
  * Check if input (an array of $_FILES) are .tar or .zip files, if they
  * are then these get unpacked and returns an managed as $_FILES (returning
  * an array with the same structure $_FILES uses and move pics to /tmp)
  *
  * @access  public
  * @param   array   $files   $_FILES
  * @return  array   $_FILES format
  */
 function UnpackFiles($files)
 {
     if (!is_array($files)) {
         return array();
     }
     $cleanFiles = array();
     $tmpDir = sys_get_temp_dir();
     $counter = 1;
     require_once PEAR_PATH . 'File/Archive.php';
     foreach ($files as $key => $file) {
         if (empty($file['tmp_name'])) {
             continue;
         }
         $ext = strrchr($file['name'], '.');
         switch ($ext) {
             case '.gz':
                 $ext = '.tgz';
                 break;
             case '.bz2':
             case '.bzip2':
                 $ext = '.tbz';
                 break;
         }
         $ext = strtolower(ltrim($ext, '.'));
         if (File_Archive::isKnownExtension($ext)) {
             $tmpArchiveName = $tmpDir . DIRECTORY_SEPARATOR . $file['name'];
             if (!move_uploaded_file($file['tmp_name'], $tmpArchiveName)) {
                 continue;
             }
             $reader = File_Archive::read($tmpArchiveName);
             $source = File_Archive::readArchive($ext, $reader);
             if (!PEAR::isError($source)) {
                 while ($source->next()) {
                     $destFile = $tmpDir . DIRECTORY_SEPARATOR . basename($source->getFilename());
                     $sourceFile = $tmpArchiveName . '/' . $source->getFilename();
                     $extract = File_Archive::extract($sourceFile, $tmpDir);
                     if (PEAR::IsError($extract)) {
                         continue;
                     }
                     $cleanFiles['photo' . $counter] = array('name' => basename($source->getFilename()), 'type' => $source->getMime(), 'tmp_name' => $destFile, 'size' => @filesize($destFile), 'error' => 0);
                     $counter++;
                 }
             }
         } else {
             $cleanFiles['photo' . $counter] = $file;
             $counter++;
         }
     }
     return $cleanFiles;
 }
Example #2
0
function &getDB($bNew = false, $bPersistent = false)
{
    // Get the database object
    $oDB =& DB::connect(CONST_Database_DSN . ($bNew ? '?new_link=true' : ''), $bPersistent);
    if (PEAR::IsError($oDB)) {
        var_dump(CONST_Database_DSN);
        var_Dump($oDB);
        fail($oDB->getMessage());
    }
    $oDB->setFetchMode(DB_FETCHMODE_ASSOC);
    $oDB->query("SET DateStyle TO 'sql,european'");
    $oDB->query("SET client_encoding TO 'utf-8'");
    return $oDB;
}
Example #3
0
        //var_dump($sSQL);
        $aPlace = $oDB->getRow($sSQL);
        $iPlaceID = $aPlace['place_id'];
        $iParentPlaceID = $aPlace['parent_place_id'];
        if (PEAR::IsError($iPlaceID)) {
            failInternalError("Could not determine closest place.", $sSQL, $iPlaceID);
        }
    }
    // The point we found might be too small - use the address to find what it is a child of
    if ($iPlaceID && $iMaxRank < 28) {
        if ($aPlace['rank_search'] > 28 && $iParentPlaceID) {
            $iPlaceID = $iParentPlaceID;
        }
        $sSQL = "select address_place_id from place_addressline where place_id = {$iPlaceID} order by abs(cached_rank_address - {$iMaxRank}) asc,cached_rank_address desc,isaddress desc,distance desc limit 1";
        $iPlaceID = $oDB->getOne($sSQL);
        if (PEAR::IsError($iPlaceID)) {
            failInternalError("Could not get parent for place.", $sSQL, $iPlaceID);
        }
        if (!$iPlaceID) {
            $iPlaceID = $aPlace['place_id'];
        }
    }
}
if ($iPlaceID) {
    $sSQL = "select placex.*,";
    $sSQL .= " get_address_by_language(place_id, {$sLanguagePrefArraySQL}) as langaddress,";
    $sSQL .= " get_name_by_language(name, {$sLanguagePrefArraySQL}) as placename,";
    $sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,";
    $sSQL .= " st_y(st_centroid(geometry)) as lat, st_x(st_centroid(geometry)) as lon";
    $sSQL .= " from placex where place_id = {$iPlaceID} ";
    //var_dump($sSQL);
Example #4
0
 /**
  * Get the stucture of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure.
  *          The returned array contains an array for each field definition,
  *          with (some of) these indices:
  *          [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $query = "SELECT sql FROM sqlite_master WHERE type='table' AND ";
     if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
         $query .= 'LOWER(name)=' . $db->quote(strtolower($table), 'text');
     } else {
         $query .= 'name=' . $db->quote($table, 'text');
     }
     $sql = $db->queryOne($query);
     if (PEAR::isError($sql)) {
         return $sql;
     }
     $columns = $this->_getTableColumns($sql);
     foreach ($columns as $column) {
         if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
             if ($db->options['field_case'] == CASE_LOWER) {
                 $column['name'] = strtolower($column['name']);
             } else {
                 $column['name'] = strtoupper($column['name']);
             }
         } else {
             $column = array_change_key_case($column, $db->options['field_case']);
         }
         if ($field_name == $column['name']) {
             $mapped_datatype = $db->datatype->mapNativeDatatype($column);
             if (PEAR::IsError($mapped_datatype)) {
                 return $mapped_datatype;
             }
             list($types, $length, $unsigned, $fixed) = $mapped_datatype;
             $notnull = false;
             if (!empty($column['notnull'])) {
                 $notnull = $column['notnull'];
             }
             $default = false;
             if (array_key_exists('default', $column)) {
                 $default = $column['default'];
                 if (is_null($default) && $notnull) {
                     $default = '';
                 }
             }
             $autoincrement = false;
             if (!empty($column['autoincrement'])) {
                 $autoincrement = true;
             }
             $definition[0] = array('notnull' => $notnull, 'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type']));
             if (!is_null($length)) {
                 $definition[0]['length'] = $length;
             }
             if (!is_null($unsigned)) {
                 $definition[0]['unsigned'] = $unsigned;
             }
             if (!is_null($fixed)) {
                 $definition[0]['fixed'] = $fixed;
             }
             if ($default !== false) {
                 $definition[0]['default'] = $default;
             }
             if ($autoincrement !== false) {
                 $definition[0]['autoincrement'] = $autoincrement;
             }
             foreach ($types as $key => $type) {
                 $definition[$key] = $definition[0];
                 if ($type == 'clob' || $type == 'blob') {
                     unset($definition[$key]['default']);
                 }
                 $definition[$key]['type'] = $type;
                 $definition[$key]['mdb2type'] = $type;
             }
             return $definition;
         }
     }
     return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
 }
Example #5
0
 function getAddressDetails($bAll = false)
 {
     if (!$this->iPlaceID) {
         return null;
     }
     $sLanguagePrefArraySQL = "ARRAY[" . join(',', array_map("getDBQuoted", $this->aLangPrefOrder)) . "]";
     $sSQL = "select *,get_name_by_language(name,{$sLanguagePrefArraySQL}) as localname from get_addressdata(" . $this->iPlaceID . ")";
     if (!$bAll) {
         $sSQL .= " WHERE isaddress OR type = 'country_code'";
     }
     $sSQL .= " order by rank_address desc,isaddress desc";
     $aAddressLines = $this->oDB->getAll($sSQL);
     if (PEAR::IsError($aAddressLines)) {
         var_dump($aAddressLines);
         exit;
     }
     return $aAddressLines;
 }
Example #6
0
$iZoom = 14;
$aClassType = getClassTypesWithImportance();
$aPointDetails['icon'] = $aClassType[$aPointDetails['class'] . ':' . $aPointDetails['type']]['icon'];
// Get all alternative names (languages, etc)
$sSQL = "select (each(name)).key,(each(name)).value from placex where place_id = {$iPlaceID} order by (each(name)).key";
$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
// Extra tags
$sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = {$iPlaceID} order by (each(extratags)).key";
$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
// Get the bounding box and outline polygon
$sSQL = "select ST_AsText(geometry) as outlinestring,";
$sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
$sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
$sSQL .= " from placex where place_id = {$iPlaceID}";
$aPointPolygon = $oDB->getRow($sSQL);
if (PEAR::IsError($aPointPolygon)) {
    failInternalError("Could not get bounding box of place object.", $sSQL, $aPointPolygon);
}
if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#', $aPointPolygon['outlinestring'], $aMatch)) {
    preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
} elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#', $aPointPolygon['outlinestring'], $aMatch)) {
    // TODO: this just takes the first ring
    preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
} elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#', $aPointPolygon['outlinestring'], $aMatch)) {
    $fRadius = 0.01;
    if ($aPointDetails['rank_search'] > 20) {
        $fRadius = 0.0001;
    }
    $iSteps = min(max($fRadius * 40000 ^ 2, 16), 100);
    $fStepSize = 2 * pi() / $iSteps;
    $aPolyPoints = array();
Example #7
0
 /**
  * Get the structure of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $query = "SELECT a.attname AS name,\r\n                         t.typname AS type,\r\n                         CASE a.attlen\r\n                           WHEN -1 THEN\r\n\t                         CASE t.typname\r\n\t                           WHEN 'numeric' THEN (a.atttypmod / 65536)\r\n\t                           WHEN 'decimal' THEN (a.atttypmod / 65536)\r\n\t                           WHEN 'money'   THEN (a.atttypmod / 65536)\r\n\t                           ELSE CASE a.atttypmod\r\n                                 WHEN -1 THEN NULL\r\n\t                             ELSE a.atttypmod - 4\r\n\t                           END\r\n                             END\r\n\t                       ELSE a.attlen\r\n                         END AS length,\r\n\t                     CASE t.typname\r\n\t                       WHEN 'numeric' THEN (a.atttypmod % 65536) - 4\r\n\t                       WHEN 'decimal' THEN (a.atttypmod % 65536) - 4\r\n\t                       WHEN 'money'   THEN (a.atttypmod % 65536) - 4\r\n\t                       ELSE 0\r\n                         END AS scale,\r\n                         a.attnotnull,\r\n                         a.atttypmod,\r\n                         a.atthasdef,\r\n                         (SELECT substring(pg_get_expr(d.adbin, d.adrelid) for 128)\r\n                            FROM pg_attrdef d\r\n                           WHERE d.adrelid = a.attrelid\r\n                             AND d.adnum = a.attnum\r\n                             AND a.atthasdef\r\n                         ) as default\r\n                    FROM pg_attribute a,\r\n                         pg_class c,\r\n                         pg_type t\r\n                   WHERE c.relname = " . $db->quote($table, 'text') . "\r\n                     AND a.atttypid = t.oid\r\n                     AND c.oid = a.attrelid\r\n                     AND NOT a.attisdropped\r\n                     AND a.attnum > 0\r\n                     AND a.attname = " . $db->quote($field_name, 'text') . "\r\n                ORDER BY a.attnum";
     $column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
     if (PEAR::isError($column)) {
         return $column;
     }
     if (empty($column)) {
         return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
     }
     $column = array_change_key_case($column, CASE_LOWER);
     $mapped_datatype = $db->datatype->mapNativeDatatype($column);
     if (PEAR::IsError($mapped_datatype)) {
         return $mapped_datatype;
     }
     list($types, $length, $unsigned, $fixed) = $mapped_datatype;
     $notnull = false;
     if (!empty($column['attnotnull']) && $column['attnotnull'] == 't') {
         $notnull = true;
     }
     $default = null;
     if ($column['atthasdef'] === 't' && !preg_match("/nextval\\('([^']+)'/", $column['default'])) {
         $default = $column['default'];
         #substr($column['adsrc'], 1, -1);
         if (is_null($default) && $notnull) {
             $default = '';
         }
     }
     $autoincrement = false;
     if (preg_match("/nextval\\('([^']+)'/", $column['default'], $nextvals)) {
         $autoincrement = true;
     }
     $definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
     if (!is_null($length)) {
         $definition[0]['length'] = $length;
     }
     if (!is_null($unsigned)) {
         $definition[0]['unsigned'] = $unsigned;
     }
     if (!is_null($fixed)) {
         $definition[0]['fixed'] = $fixed;
     }
     if ($default !== false) {
         $definition[0]['default'] = $default;
     }
     if ($autoincrement !== false) {
         $definition[0]['autoincrement'] = $autoincrement;
     }
     foreach ($types as $key => $type) {
         $definition[$key] = $definition[0];
         if ($type == 'clob' || $type == 'blob') {
             unset($definition[$key]['default']);
         }
         $definition[$key]['type'] = $type;
         $definition[$key]['mdb2type'] = $type;
     }
     return $definition;
 }
Example #8
0
 /**
  * Get the structure of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $table = $db->quoteIdentifier($table, true);
     $query = "SHOW COLUMNS FROM {$table} LIKE " . $db->quote($field_name);
     $columns = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
     if (PEAR::isError($columns)) {
         return $columns;
     }
     foreach ($columns as $column) {
         $column = array_change_key_case($column, CASE_LOWER);
         $column['name'] = $column['field'];
         unset($column['field']);
         if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
             if ($db->options['field_case'] == CASE_LOWER) {
                 $column['name'] = strtolower($column['name']);
             } else {
                 $column['name'] = strtoupper($column['name']);
             }
         } else {
             $column = array_change_key_case($column, $db->options['field_case']);
         }
         if ($field_name == $column['name']) {
             $mapped_datatype = $db->datatype->mapNativeDatatype($column);
             if (PEAR::IsError($mapped_datatype)) {
                 return $mapped_datatype;
             }
             list($types, $length, $unsigned, $fixed) = $mapped_datatype;
             $notnull = false;
             if (empty($column['null']) || $column['null'] !== 'YES') {
                 $notnull = true;
             }
             $default = false;
             if (array_key_exists('default', $column)) {
                 $default = $column['default'];
                 if (is_null($default) && $notnull) {
                     $default = '';
                 }
             }
             $autoincrement = false;
             if (!empty($column['extra']) && $column['extra'] == 'auto_increment') {
                 $autoincrement = true;
             }
             $definition[0] = array('notnull' => $notnull, 'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type']));
             if (!is_null($length)) {
                 $definition[0]['length'] = $length;
             }
             if (!is_null($unsigned)) {
                 $definition[0]['unsigned'] = $unsigned;
             }
             if (!is_null($fixed)) {
                 $definition[0]['fixed'] = $fixed;
             }
             if ($default !== false) {
                 $definition[0]['default'] = $default;
             }
             if ($autoincrement !== false) {
                 $definition[0]['autoincrement'] = $autoincrement;
             }
             foreach ($types as $key => $type) {
                 $definition[$key] = $definition[0];
                 if ($type == 'clob' || $type == 'blob') {
                     unset($definition[$key]['default']);
                 }
                 $definition[$key]['type'] = $type;
                 $definition[$key]['mdb2type'] = $type;
             }
             return $definition;
         }
     }
     return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
 }
Example #9
0
 /**
  * Get the structure of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $table = $db->quoteIdentifier($table, true);
     $fldname = $db->quoteIdentifier($field_name, true);
     $query = "SELECT t.table_name,\n                         c.column_name 'name',\n                         c.data_type 'type',\n                         CASE c.is_nullable WHEN 'YES' THEN 1 ELSE 0 END AS 'is_nullable',\n                \t\t c.column_default,\n                \t\t c.character_maximum_length 'length',\n                         c.numeric_precision,\n                         c.numeric_scale,\n                         c.character_set_name,\n                         c.collation_name\n                    FROM INFORMATION_SCHEMA.TABLES t,\n                         INFORMATION_SCHEMA.COLUMNS c\n                   WHERE t.table_name = c.table_name\n                     AND t.table_name = '{$table}'\n                     AND c.column_name = '{$fldname}'\n                ORDER BY t.table_name";
     $column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
     if (PEAR::isError($column)) {
         return $column;
     }
     if (empty($column)) {
         return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
     }
     if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
         if ($db->options['field_case'] == CASE_LOWER) {
             $column['name'] = strtolower($column['name']);
         } else {
             $column['name'] = strtoupper($column['name']);
         }
     } else {
         $column = array_change_key_case($column, $db->options['field_case']);
     }
     $mapped_datatype = $db->datatype->mapNativeDatatype($column);
     if (PEAR::IsError($mapped_datatype)) {
         return $mapped_datatype;
     }
     list($types, $length, $unsigned, $fixed) = $mapped_datatype;
     $notnull = true;
     if ($column['is_nullable']) {
         $notnull = false;
     }
     $default = false;
     if (array_key_exists('column_default', $column)) {
         $default = $column['column_default'];
         if (is_null($default) && $notnull) {
             $default = '';
         } elseif (strlen($default) > 4 && substr($default, 0, 1) == '(' && substr($default, -1, 1) == ')') {
             //mssql wraps the default value in parentheses: "((1234))", "(NULL)"
             $default = trim($default, '()');
             if ($default == 'NULL') {
                 $default = null;
             }
         }
     }
     $definition[0] = array('notnull' => $notnull, 'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type']));
     if (!is_null($length)) {
         $definition[0]['length'] = $length;
     }
     if (!is_null($unsigned)) {
         $definition[0]['unsigned'] = $unsigned;
     }
     if (!is_null($fixed)) {
         $definition[0]['fixed'] = $fixed;
     }
     if ($default !== false) {
         $definition[0]['default'] = $default;
     }
     foreach ($types as $key => $type) {
         $definition[$key] = $definition[0];
         if ($type == 'clob' || $type == 'blob') {
             unset($definition[$key]['default']);
         }
         $definition[$key]['type'] = $type;
         $definition[$key]['mdb2type'] = $type;
     }
     return $definition;
 }
Example #10
0
 /**
  * Get the structure of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $table = $db->quote(strtoupper($table), 'text');
     $field_name = $db->quote(strtoupper($field_name), 'text');
     $query = "SELECT RDB\$RELATION_FIELDS.RDB\$FIELD_NAME AS name,\n                         RDB\$FIELDS.RDB\$FIELD_LENGTH AS \"length\",\n                         RDB\$FIELDS.RDB\$FIELD_PRECISION AS \"precision\",\n                         (RDB\$FIELDS.RDB\$FIELD_SCALE * -1) AS \"scale\",\n                         RDB\$FIELDS.RDB\$FIELD_TYPE AS field_type_code,\n                         RDB\$FIELDS.RDB\$FIELD_SUB_TYPE AS field_sub_type_code,\n                         RDB\$RELATION_FIELDS.RDB\$DESCRIPTION AS description,\n                         RDB\$RELATION_FIELDS.RDB\$NULL_FLAG AS null_flag,\n                         RDB\$FIELDS.RDB\$DEFAULT_SOURCE AS default_source\n                    FROM RDB\$FIELDS\n               LEFT JOIN RDB\$RELATION_FIELDS ON RDB\$FIELDS.RDB\$FIELD_NAME = RDB\$RELATION_FIELDS.RDB\$FIELD_SOURCE\n                   WHERE UPPER(RDB\$RELATION_FIELDS.RDB\$RELATION_NAME)={$table}\n                     AND UPPER(RDB\$RELATION_FIELDS.RDB\$FIELD_NAME)={$field_name};";
     $column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
     if (PEAR::isError($column)) {
         return $column;
     }
     if (empty($column)) {
         return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
     }
     $column = array_change_key_case($column, CASE_LOWER);
     if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
         if ($db->options['field_case'] == CASE_LOWER) {
             $column['name'] = strtolower($column['name']);
         } else {
             $column['name'] = strtoupper($column['name']);
         }
     }
     $column['type'] = array_key_exists((int) $column['field_type_code'], $this->types) ? $this->types[(int) $column['field_type_code']] : 'undefined';
     if ($column['field_sub_type_code'] && array_key_exists((int) $column['field_type_code'], $this->subtypes) && array_key_exists($column['field_sub_type_code'], $this->subtypes[(int) $column['field_type_code']])) {
         $column['field_sub_type'] = $this->subtypes[(int) $column['field_type_code']][$column['field_sub_type_code']];
     } else {
         $column['field_sub_type'] = null;
     }
     $mapped_datatype = $db->datatype->mapNativeDatatype($column);
     if (PEAR::IsError($mapped_datatype)) {
         return $mapped_datatype;
     }
     list($types, $length, $unsigned, $fixed) = $mapped_datatype;
     $notnull = !empty($column['null_flag']);
     $default = $column['default_source'];
     if (is_null($default) && $notnull) {
         $default = $types[0] == 'integer' ? 0 : '';
     }
     $definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
     if (!is_null($length)) {
         $definition[0]['length'] = $length;
     }
     if (!is_null($unsigned)) {
         $definition[0]['unsigned'] = $unsigned;
     }
     if (!is_null($fixed)) {
         $definition[0]['fixed'] = $fixed;
     }
     if ($default !== false) {
         $definition[0]['default'] = $default;
     }
     foreach ($types as $key => $type) {
         $definition[$key] = $definition[0];
         if ($type == 'clob' || $type == 'blob') {
             unset($definition[$key]['default']);
         }
         $definition[$key]['type'] = $type;
         $definition[$key]['mdb2type'] = $type;
     }
     return $definition;
 }
Example #11
0
 function getOutlines($iPlaceID, $fLon = null, $fLat = null, $fRadius = null)
 {
     $aOutlineResult = array();
     if (!$iPlaceID) {
         return $aOutlineResult;
     }
     if (CONST_Search_AreaPolygons) {
         // Get the bounding box and outline polygon
         $sSQL = "select place_id,0 as numfeatures,st_area(geometry) as area,";
         $sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
         $sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
         $sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
         if ($this->bIncludePolygonAsGeoJSON) {
             $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson";
         }
         if ($this->bIncludePolygonAsKML) {
             $sSQL .= ",ST_AsKML(geometry) as askml";
         }
         if ($this->bIncludePolygonAsSVG) {
             $sSQL .= ",ST_AsSVG(geometry) as assvg";
         }
         if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) {
             $sSQL .= ",ST_AsText(geometry) as astext";
         }
         $sFrom = " from placex where place_id = " . $iPlaceID;
         if ($this->fPolygonSimplificationThreshold > 0) {
             $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry," . $this->fPolygonSimplificationThreshold . ") as geometry" . $sFrom . ") as plx";
         } else {
             $sSQL .= $sFrom;
         }
         $aPointPolygon = $this->oDB->getRow($sSQL);
         if (PEAR::IsError($aPointPolygon)) {
             echo var_dump($aPointPolygon);
             failInternalError("Could not get outline.", $sSQL, $aPointPolygon);
         }
         if ($aPointPolygon['place_id']) {
             if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null) {
                 $aOutlineResult['lat'] = $aPointPolygon['centrelat'];
                 $aOutlineResult['lon'] = $aPointPolygon['centrelon'];
             }
             if ($this->bIncludePolygonAsGeoJSON) {
                 $aOutlineResult['asgeojson'] = $aPointPolygon['asgeojson'];
             }
             if ($this->bIncludePolygonAsKML) {
                 $aOutlineResult['askml'] = $aPointPolygon['askml'];
             }
             if ($this->bIncludePolygonAsSVG) {
                 $aOutlineResult['assvg'] = $aPointPolygon['assvg'];
             }
             if ($this->bIncludePolygonAsText) {
                 $aOutlineResult['astext'] = $aPointPolygon['astext'];
             }
             if ($this->bIncludePolygonAsPoints) {
                 $aOutlineResult['aPolyPoints'] = geometryText2Points($aPointPolygon['astext'], $fRadius);
             }
             if (abs($aPointPolygon['minlat'] - $aPointPolygon['maxlat']) < 1.0E-7) {
                 $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
                 $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
             }
             if (abs($aPointPolygon['minlon'] - $aPointPolygon['maxlon']) < 1.0E-7) {
                 $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
                 $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
             }
             $aOutlineResult['aBoundingBox'] = array((string) $aPointPolygon['minlat'], (string) $aPointPolygon['maxlat'], (string) $aPointPolygon['minlon'], (string) $aPointPolygon['maxlon']);
         }
     }
     // CONST_Search_AreaPolygons
     // as a fallback we generate a bounding box without knowing the size of the geometry
     if (!isset($aOutlineResult['aBoundingBox']) && isset($fLon)) {
         if ($this->bIncludePolygonAsPoints) {
             $sGeometryText = 'POINT(' . $fLon . ',' . $fLat . ')';
             $aOutlineResult['aPolyPoints'] = geometryText2Points($sGeometryText, $fRadius);
         }
         $aBounds = array();
         $aBounds['minlat'] = $fLat - $fRadius;
         $aBounds['maxlat'] = $fLat + $fRadius;
         $aBounds['minlon'] = $fLon - $fRadius;
         $aBounds['maxlon'] = $fLon + $fRadius;
         $aOutlineResult['aBoundingBox'] = array((string) $aBounds['minlat'], (string) $aBounds['maxlat'], (string) $aBounds['minlon'], (string) $aBounds['maxlon']);
     }
     return $aOutlineResult;
 }
Example #12
0
#   http://pear.php.net/manual/en/package.mail.mail-mime.php
##---------------------------------------------------
## OBSERVAÇÃO: Caso deseje um exemplo de como enviar arquivos em anexo,
##             gere um script com "Formato do e-mail" igual a "HTML".
# Faz o include do PEAR Mail.
include "Mail.php";
# E-mail de destino. Caso seja mais de um destino, crie um array de e-mails.
# *OBRIGATÓRIO*
$recipients = '*****@*****.**';
# Cabeçalho do e-mail.
$headers = array('From' => '*****@*****.**', 'To' => '*****@*****.**', 'Subject' => $motivo, 'Date' => date('r'), 'Reply-To' => $email);
# Utilize esta opção caso deseje definir o e-mail de resposta
# $headers['Reply-To'] = '*****@*****.**';
# Utilize esta opção caso deseje definir o e-mail de retorno em caso de erro de envio
# $headers['Errors-To'] = '*****@*****.**';
# Utilize esta opção caso deseje definir a prioridade do e-mail
# $headers['X-Priority'] = '3'; # 1 UrgentMessage, 3 Normal
# Corpo da Mensagem
$body = $txt;
# Parâmetros para o SMTP. *OBRIGATÓRIO*
$params = array('auth' => true, 'host' => 'smtp.funcionalstudio.com.br', 'username' => 'contato=funcionalstudio.com.br', 'password' => 'contato5535');
# Define o método de envio! queremos 'smtp'. *OBRIGATÓRIO*
$mail_object =& Mail::factory('smtp', $params);
# Envia o email. Se não ocorrer erro, retorna TRUE caso contrário, retorna um
# objeto PEAR_Error. Para ler a mensagem de erro, use o método 'getMessage()'.
$result = $mail_object->send($recipients, $headers, $body);
if (PEAR::IsError($result)) {
    echo "<script>alert('Erro ao enviar o e-mail. Tente novamente por favor.');window.location.href='http://'+window.location.hostname+'/contato.html';</script>";
} else {
    echo "<script>alert('E-mail enviado com sucesso!');window.location.href='http://'+window.location.hostname+'/contato.html';</script>";
}
Example #13
0
 function lookup()
 {
     $sPointSQL = 'ST_SetSRID(ST_Point(' . $this->fLon . ',' . $this->fLat . '),4326)';
     $iMaxRank = $this->iMaxRank;
     $iMaxRank_orig = $this->iMaxRank;
     // Find the nearest point
     $fSearchDiam = 0.0004;
     $iPlaceID = null;
     $aArea = false;
     $fMaxAreaDistance = 1;
     $bIsInUnitedStates = false;
     $bPlaceIsTiger = false;
     while (!$iPlaceID && $fSearchDiam < $fMaxAreaDistance) {
         $fSearchDiam = $fSearchDiam * 2;
         // If we have to expand the search area by a large amount then we need a larger feature
         // then there is a limit to how small the feature should be
         if ($fSearchDiam > 2 && $iMaxRank > 4) {
             $iMaxRank = 4;
         }
         if ($fSearchDiam > 1 && $iMaxRank > 9) {
             $iMaxRank = 8;
         }
         if ($fSearchDiam > 0.8 && $iMaxRank > 10) {
             $iMaxRank = 10;
         }
         if ($fSearchDiam > 0.6 && $iMaxRank > 12) {
             $iMaxRank = 12;
         }
         if ($fSearchDiam > 0.2 && $iMaxRank > 17) {
             $iMaxRank = 17;
         }
         if ($fSearchDiam > 0.1 && $iMaxRank > 18) {
             $iMaxRank = 18;
         }
         if ($fSearchDiam > 0.008 && $iMaxRank > 22) {
             $iMaxRank = 22;
         }
         if ($fSearchDiam > 0.001 && $iMaxRank > 26) {
             $iMaxRank = 26;
         }
         $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code from placex';
         $sSQL .= ' WHERE ST_DWithin(' . $sPointSQL . ', geometry, ' . $fSearchDiam . ')';
         $sSQL .= ' and rank_search != 28 and rank_search >= ' . $iMaxRank;
         $sSQL .= ' and (name is not null or housenumber is not null)';
         $sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\',\'man_made\')';
         $sSQL .= ' and indexed_status = 0 ';
         $sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ';
         $sSQL .= ' OR ST_DWithin(' . $sPointSQL . ', centroid, ' . $fSearchDiam . '))';
         $sSQL .= ' ORDER BY ST_distance(' . $sPointSQL . ', geometry) ASC limit 1';
         if (CONST_Debug) {
             var_dump($sSQL);
         }
         $aPlace = $this->oDB->getRow($sSQL);
         if (PEAR::IsError($aPlace)) {
             failInternalError("Could not determine closest place.", $sSQL, $aPlace);
         }
         $iPlaceID = $aPlace['place_id'];
         $iParentPlaceID = $aPlace['parent_place_id'];
         $bIsInUnitedStates = $aPlace['calculated_country_code'] == 'us';
     }
     // Only street found? If it's in the US we can check TIGER data for nearest housenumber
     if ($bIsInUnitedStates && $iMaxRank_orig >= 28 && $iPlaceID && ($aPlace['rank_search'] == 26 || $aPlace['rank_search'] == 27)) {
         $fSearchDiam = 0.001;
         $sSQL = 'SELECT place_id,parent_place_id,30 as rank_search ';
         if (CONST_Debug) {
             $sSQL .= ', housenumber, ST_distance(' . $sPointSQL . ', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon';
         }
         $sSQL .= ' FROM location_property_tiger WHERE parent_place_id = ' . $iPlaceID;
         $sSQL .= ' AND ST_DWithin(' . $sPointSQL . ', centroid, ' . $fSearchDiam . ')';
         $sSQL .= ' ORDER BY ST_distance(' . $sPointSQL . ', centroid) ASC limit 1';
         // print all house numbers in the parent (street)
         if (CONST_Debug) {
             $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
             var_dump($sSQL);
             $aAllHouses = $this->oDB->getAll($sSQL);
             foreach ($aAllHouses as $i) {
                 echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon'] . ' | ' . "<br>\n";
             }
         }
         $aPlaceTiger = $this->oDB->getRow($sSQL);
         if (PEAR::IsError($aPlace)) {
             failInternalError("Could not determine closest Tiger place.", $sSQL, $aPlaceTiger);
         }
         if ($aPlaceTiger) {
             if (CONST_Debug) {
                 var_dump('found Tiger place', $aPlaceTiger);
             }
             $bPlaceIsTiger = true;
             $aPlace = $aPlaceTiger;
             $iPlaceID = $aPlaceTiger['place_id'];
             $iParentPlaceID = $aPlaceTiger['parent_place_id'];
             // the street
         }
     }
     // The point we found might be too small - use the address to find what it is a child of
     if ($iPlaceID && $iMaxRank < 28) {
         if ($aPlace['rank_search'] > 28 && $iParentPlaceID && !$bPlaceIsTiger) {
             $iPlaceID = $iParentPlaceID;
         }
         $sSQL = "select address_place_id from place_addressline where place_id = {$iPlaceID} order by abs(cached_rank_address - {$iMaxRank}) asc,cached_rank_address desc,isaddress desc,distance desc limit 1";
         $iPlaceID = $this->oDB->getOne($sSQL);
         if (PEAR::IsError($iPlaceID)) {
             failInternalError("Could not get parent for place.", $sSQL, $iPlaceID);
         }
         if (!$iPlaceID) {
             $iPlaceID = $aPlace['place_id'];
         }
     }
     return array('place_id' => $iPlaceID, 'type' => $bPlaceIsTiger ? 'tiger' : 'osm');
 }
Example #14
0
	/**
	 * send()
	 *
	 * Method to send the prepared email, the prepare method
	 * must be called prior to calling this function.
	 *
	 * %attachments must be an associative array with the
	 * following stucture.
	 * $attachments['data'] = The actual attachment data
	 * $attachments['name'] = The filename of the attachment
	 * $attachments['type'] = The mime content type, defaults to application/octet-stream
	 * $attachments['encoding'] = The type of encoding to be used, defaults to base64
	 *
	 * $headers must be an associative array with the
	 * key being the header name like so.
	 * $header['Reply-To'] = "*****@*****.**"
	 *
	 * If you include values for Subject or From in the $headers
	 * array they will be used instead of the respective values
	 * from the prepared notification
	 *
	 * @param array $attachments Array of items to attach
	 * @param array $headers Array of additonal headers to be included
	 * @return boolean TRUE on success, FALSE on error. See getLastError() for the reason
	 */
	function send($attachments = NULL, $headers = NULL){

		if($this->active == 'N'){
			$this->error = "Notification::send(): Skipping inactive message!";
			return TRUE;
		}

		if(empty($this->prepared_body) || empty($this->prepared_addresses)){
			$this->error = "Notification::send(): Skipping message with empty body or addresses!";
			var_dump($this);
			var_dump($this->parameters);
			return FALSE;
		}

		if($headers != NULL && !is_array($headers)){
			$this->error = "Notification::send(): Invalid headers provided!";
			return FALSE;
		}else{
			$found_from = FALSE;
			$found_subject = FALSE;
			foreach($headers as $header => $value){
				if(strtolower($header) == "from")
					$found_from = TRUE;
				elseif(strtolower($header) == "subject")
					$found_subject = TRUE;
			}
			if(!$found_from)
				$headers['From'] = $this->prepared_from;
			if(!$found_subject)
				$headers['Subject'] = $this->prepared_subject;
		}

		$mime = new Mail_mime();
		$mime->setTXTBody($this->prepared_body);

		if(is_array($attachments) && count($attachments) > 0){
			foreach($attachments as $attach){
				if(empty($attach['data']) || empty($attach['name'])){
					$this->error = "Notification::send(): Invalid attachment!";
					return FALSE;
				}
				if(!isset($attach['type'])) $attach['type'] = 'application/octet-stream';
				if(!isset($attach['encoding'])) $attach['encoding'] = 'base64';
				$result = $mime->addAttachment($attach['data'], $attach['type'], $attach['name'], FALSE, $attach['encoding']);
				if(PEAR::IsError($result)){
					$this->error = "Notification::send(): Error adding attachment: ".$result->getMessage();
					return FALSE;
				}
			}
		}

		$message = $mime->get();
		$headers = $mime->headers($headers);
		$mailer = Mail::factory('mail');
		$result = $mailer->send($this->prepared_addresses, $headers, $message);
		if(PEAR::IsError($result)){
			$this->error = "Notification::send(): Error sending message: ".$result->getMessage();
			return FALSE;
		}

		return TRUE;
	}
Example #15
0
 /**
  * Get the structure of a field into an array
  *
  * @param string    $table       name of table that should be used in method
  * @param string    $field_name  name of field that should be used in method
  * @return mixed data array on success, a MDB2 error on failure
  * @access public
  */
 function getTableFieldDefinition($table, $field_name)
 {
     $db =& $this->getDBInstance();
     if (PEAR::isError($db)) {
         return $db;
     }
     $result = $db->loadModule('Datatype', null, true);
     if (PEAR::isError($result)) {
         return $result;
     }
     $query = 'SELECT column_name name, data_type "type", nullable, data_default "default"';
     $query .= ', COALESCE(data_precision, data_length) "length", data_scale "scale"';
     $query .= ' FROM user_tab_columns';
     $query .= ' WHERE (table_name=' . $db->quote($table, 'text') . ' OR table_name=' . $db->quote(strtoupper($table), 'text') . ')';
     $query .= ' AND (column_name=' . $db->quote($field_name, 'text') . ' OR column_name=' . $db->quote(strtoupper($field_name), 'text') . ')';
     $query .= ' ORDER BY column_id';
     $column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
     if (PEAR::isError($column)) {
         return $column;
     }
     if (empty($column)) {
         return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'it was not specified an existing table column', __FUNCTION__);
     }
     $column = array_change_key_case($column, CASE_LOWER);
     if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
         if ($db->options['field_case'] == CASE_LOWER) {
             $column['name'] = strtolower($column['name']);
         } else {
             $column['name'] = strtoupper($column['name']);
         }
     }
     $mapped_datatype = $db->datatype->mapNativeDatatype($column);
     if (PEAR::IsError($mapped_datatype)) {
         return $mapped_datatype;
     }
     list($types, $length, $unsigned, $fixed) = $mapped_datatype;
     $notnull = false;
     if (!empty($column['nullable']) && $column['nullable'] == 'N') {
         $notnull = true;
     }
     $default = false;
     if (array_key_exists('default', $column)) {
         $default = $column['default'];
         if ($default === 'NULL') {
             $default = null;
         }
         if (is_null($default) && $notnull) {
             $default = '';
         }
     }
     $definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
     if (!is_null($length)) {
         $definition[0]['length'] = $length;
     }
     if (!is_null($unsigned)) {
         $definition[0]['unsigned'] = $unsigned;
     }
     if (!is_null($fixed)) {
         $definition[0]['fixed'] = $fixed;
     }
     if ($default !== false) {
         $definition[0]['default'] = $default;
     }
     foreach ($types as $key => $type) {
         $definition[$key] = $definition[0];
         if ($type == 'clob' || $type == 'blob') {
             unset($definition[$key]['default']);
         }
         $definition[$key]['type'] = $type;
         $definition[$key]['mdb2type'] = $type;
     }
     if ($type == 'integer') {
         $query = "SELECT DISTINCT name\r\n                        FROM all_source\r\n                       WHERE type='TRIGGER'\r\n                         AND UPPER(text) like '%ON " . strtoupper($db->escape($table, 'text')) . "%'";
         $result = $db->query($query);
         if (!PEAR::isError($result)) {
             while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) {
                 $row = array_change_key_case($row, CASE_LOWER);
                 $trquery = 'SELECT text
                               FROM all_source
                              WHERE name=' . $db->quote($row['name'], 'text') . ' ORDER BY line';
                 $triggersth = $db->query($trquery);
                 $triggerstr = '';
                 while ($triggerline = $triggersth->fetchRow(MDB2_FETCHMODE_ASSOC)) {
                     $triggerline = array_change_key_case($triggerline, CASE_LOWER);
                     $triggerstr .= $triggerline['text'] . ' ';
                 }
                 $matches = array();
                 if (preg_match('/.*\\W(.+)\\.nextval into :NEW\\.' . $field_name . ' FROM dual/i', $triggerstr, $matches)) {
                     // we reckon it's an autoincrementing trigger on field_name
                     // there will be other pcre patterns needed here for other ways of mimicking auto_increment in ora.
                     $definition[0]['autoincrement'] = $matches[1];
                 }
             }
         }
     }
     return $definition;
 }
Example #16
0
function indexSector($oDB, $aSector, $fMaxBlocking, $fMaxLoad)
{
    $iNum = $aSector['count'];
    $iRank = $aSector['rank'];
    $fNumSteps = ceil(sqrt($iNum) / 10);
    $iNumSteps = $fNumSteps * $fNumSteps;
    if ($fNumSteps > 1) {
        $iStepNum = 1;
        echo "Spliting into " . $fNumSteps * $fNumSteps . " steps\n";
        // Convert sector number back to lat lon
        $fLon = 500 - floor($aSector['geometry_index'] / 1000) - 0.5;
        $fLat = 500 - $aSector['geometry_index'] % 1000 - 0.5;
        $fStepSize = 1 / $fNumSteps;
        for ($fStepLat = $fLat; $fStepLat < $fLat + 1; $fStepLat += $fStepSize) {
            for ($fStepLon = $fLon; $fStepLon < $fLon + 1; $fStepLon += $fStepSize) {
                while (getBlockingProcesses() > $fMaxBlocking || getLoadAverage() > $fMaxLoad) {
                    echo "System busy, pausing indexing...\n";
                    sleep(60);
                }
                $fStepLonTop = $fStepLon + $fStepSize;
                $fStepLatTop = $fStepLat + $fStepSize;
                echo "  Step {$iStepNum} of {$iNumSteps}: ({$fStepLon},{$fStepLat},{$fStepLonTop},{$fStepLatTop})\n";
                $sSQL = 'update placex set indexed = true where geometry_index(geometry,indexed,name) = ' . $aSector['geometry_index'] . ' and rank_search = ' . $iRank;
                $sSQL .= " and ST_Contains(ST_SetSRID(ST_MakeBox2D(ST_SetSRID(ST_POINT({$fStepLon},{$fStepLat}),4326),ST_SetSRID(ST_POINT({$fStepLonTop},{$fStepLatTop}),4326)),4326),geometry)";
                if (PEAR::IsError($xError = $oDB->query($sSQL))) {
                    var_dump($xError);
                    exit;
                }
                $iStepNum++;
            }
        }
    }
    $sSQL = 'update placex set indexed = true where geometry_index(geometry,indexed,name) = ' . $aSector['geometry_index'] . ' and rank_search = ' . $iRank;
    if (PEAR::IsError($xError = $oDB->query($sSQL))) {
        var_dump($xError);
        exit;
    }
    $oDB->query($sSQL);
}
Example #17
0
}
$hLog = logStart($oDB, 'details', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
// Make sure the point we are reporting on is fully indexed
//$sSQL = "UPDATE placex set indexed = true where indexed = false and place_id = $iPlaceID";
//$oDB->query($sSQL);
// Get the details for this point
$sSQL = "select place_id, osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, calculated_country_code as country_code, importance, wikipedia,";
$sSQL .= " to_char(indexed_date, 'YYYY-MM-DD HH24:MI') as indexed_date, parent_place_id, rank_address, rank_search, get_searchrank_label(rank_search) as rank_search_label, get_name_by_language(name,{$sLanguagePrefArraySQL}) as localname, ";
$sSQL .= " ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ";
//$sSQL .= " ST_Area(geometry::geography) as area, ";
$sSQL .= " ST_y(centroid) as lat, ST_x(centroid) as lon,";
$sSQL .= " case when importance = 0 OR importance IS NULL then 0.75-(rank_search::float/40) else importance end as calculated_importance, ";
$sSQL .= " ST_AsText(CASE WHEN ST_NPoints(geometry) > 5000 THEN ST_SimplifyPreserveTopology(geometry, 0.0001) ELSE geometry END) as outlinestring";
$sSQL .= " from placex where place_id = {$iPlaceID}";
$aPointDetails = $oDB->getRow($sSQL);
if (PEAR::IsError($aPointDetails)) {
    failInternalError("Could not get details of place object.", $sSQL, $aPointDetails);
}
$aPointDetails['localname'] = $aPointDetails['localname'] ? $aPointDetails['localname'] : $aPointDetails['housenumber'];
$aClassType = getClassTypesWithImportance();
$aPointDetails['icon'] = $aClassType[$aPointDetails['class'] . ':' . $aPointDetails['type']]['icon'];
// Get all alternative names (languages, etc)
$sSQL = "select (each(name)).key,(each(name)).value from placex where place_id = {$iPlaceID} order by (each(name)).key";
$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
// Extra tags
$sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = {$iPlaceID} order by (each(extratags)).key";
$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
// Address
$aAddressLines = getAddressDetails($oDB, $sLanguagePrefArraySQL, $iPlaceID, $aPointDetails['country_code'], true);
// Linked places
$sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_distance(geometry, placegeometry) as distance, ";
Example #18
0
<?php

require_once 'settings.php';
require_once 'lib.php';
require_once 'DB.php';
if (get_magic_quotes_gpc()) {
    echo "Please disable magic quotes in your php.ini configuration";
    exit;
}
if (CONST_ClosedForIndexing && strpos(CONST_ClosedForIndexingExceptionIPs, ',' . $_SERVER["REMOTE_ADDR"] . ',') === false) {
    echo "Closed for re-indexing...";
    exit;
}
if (strpos(CONST_BlockedIPs, ',' . $_SERVER["REMOTE_ADDR"] . ',') !== false) {
    echo "Your IP has been blocked. \n";
    echo "Please create a nominatim trac ticket (http://trac.openstreetmap.org/newticket?component=nominatim) to request this to be removed. \n";
    echo "Information on the Nominatim usage policy can be found here: http://wiki.openstreetmap.org/wiki/Nominatim#Usage_Policy \n";
    exit;
}
// Get the database object
$oDB =& DB::connect(CONST_Database_DSN, false);
if (PEAR::IsError($oDB)) {
    fail($oDB->getMessage(), 'Unable to connect to the database');
}
$oDB->setFetchMode(DB_FETCHMODE_ASSOC);
$oDB->query("SET DateStyle TO 'sql,european'");
$oDB->query("SET client_encoding TO 'utf-8'");
header('Content-type: text/html; charset=utf-8');
Example #19
0
function geocodeReverse($fLat, $fLon, $iZoom = 18)
{
    $oDB =& getDB();
    $sPointSQL = "ST_SetSRID(ST_Point({$fLon},{$fLat}),4326)";
    // Zoom to rank, this could probably be calculated but a lookup gives fine control
    $aZoomRank = array(0 => 2, 1 => 2, 2 => 2, 3 => 4, 4 => 4, 5 => 8, 6 => 10, 7 => 10, 8 => 12, 9 => 12, 10 => 17, 11 => 17, 12 => 18, 13 => 18, 14 => 22, 15 => 22, 16 => 26, 17 => 26, 18 => 30, 19 => 30);
    $iMaxRank = isset($aZoomRank[$iZoom]) ? $aZoomRank[$iZoom] : 28;
    // Find the nearest point
    $fSearchDiam = 0.0001;
    $iPlaceID = null;
    $aArea = false;
    $fMaxAreaDistance = 1;
    while (!$iPlaceID && $fSearchDiam < $fMaxAreaDistance) {
        $fSearchDiam = $fSearchDiam * 2;
        // If we have to expand the search area by a large amount then we need a larger feature
        // then there is a limit to how small the feature should be
        if ($fSearchDiam > 2 && $iMaxRank > 4) {
            $iMaxRank = 4;
        }
        if ($fSearchDiam > 1 && $iMaxRank > 9) {
            $iMaxRank = 8;
        }
        if ($fSearchDiam > 0.8 && $iMaxRank > 10) {
            $iMaxRank = 10;
        }
        if ($fSearchDiam > 0.6 && $iMaxRank > 12) {
            $iMaxRank = 12;
        }
        if ($fSearchDiam > 0.2 && $iMaxRank > 17) {
            $iMaxRank = 17;
        }
        if ($fSearchDiam > 0.1 && $iMaxRank > 18) {
            $iMaxRank = 18;
        }
        if ($fSearchDiam > 0.008 && $iMaxRank > 22) {
            $iMaxRank = 22;
        }
        if ($fSearchDiam > 0.001 && $iMaxRank > 26) {
            $iMaxRank = 26;
        }
        $sSQL = 'select place_id,parent_place_id from placex';
        $sSQL .= ' WHERE ST_DWithin(' . $sPointSQL . ', geometry, ' . $fSearchDiam . ')';
        $sSQL .= ' and rank_search != 28 and rank_search >= ' . $iMaxRank;
        $sSQL .= ' and (name is not null or housenumber is not null)';
        $sSQL .= ' and class not in (\'waterway\')';
        $sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ';
        $sSQL .= ' OR ST_DWithin(' . $sPointSQL . ', ST_Centroid(geometry), ' . $fSearchDiam . '))';
        $sSQL .= ' ORDER BY ST_distance(' . $sPointSQL . ', geometry) ASC limit 1';
        //var_dump($sSQL);
        $aPlace = $oDB->getRow($sSQL);
        $iPlaceID = $aPlace['place_id'];
        if (PEAR::IsError($iPlaceID)) {
            var_Dump($sSQL, $iPlaceID);
            exit;
        }
    }
    // The point we found might be too small - use the address to find what it is a child of
    if ($iPlaceID) {
        $sSQL = "select address_place_id from place_addressline where cached_rank_address <= {$iMaxRank} and place_id = {$iPlaceID} order by cached_rank_address desc,isaddress desc,distance desc limit 1";
        $iPlaceID = $oDB->getOne($sSQL);
        if (PEAR::IsError($iPlaceID)) {
            var_Dump($sSQL, $iPlaceID);
            exit;
        }
        if ($iPlaceID && $aPlace['place_id'] && $iMaxRank < 28) {
            $sSQL = "select address_place_id from place_addressline where cached_rank_address <= {$iMaxRank} and place_id = " . $aPlace['place_id'] . " order by cached_rank_address desc,isaddress desc,distance desc";
            $iPlaceID = $oDB->getOne($sSQL);
            if (PEAR::IsError($iPlaceID)) {
                var_Dump($sSQL, $iPlaceID);
                exit;
            }
        }
        if (!$iPlaceID) {
            $iPlaceID = $aPlace['place_id'];
        }
    }
    return $iPlaceID;
}
Example #20
0
function getAddressDetails(&$oDB, $sLanguagePrefArraySQL, $iPlaceID, $sCountryCode = false, $bRaw = false)
{
    $sHouseNumber = $oDB->getOne('select housenumber from placex where place_id = ' . $iPlaceID);
    // Address
    $sSQL = "select country_code, placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, ";
    $sSQL .= "get_searchrank_label(rank_search) as rank_search_label, fromarea, isaddress, distance, ";
    $sSQL .= " CASE WHEN type = 'postcode' THEN postcode ELSE get_name_by_language(name,{$sLanguagePrefArraySQL}) END as localname, ";
    $sSQL .= " length(name::text) as namelength ";
    $sSQL .= " from place_addressline join placex on (address_place_id = placex.place_id)";
    $sSQL .= " where place_addressline.place_id = {$iPlaceID} and (rank_address > 0 OR address_place_id = {$iPlaceID})";
    // and isaddress";
    if ($sCountryCode) {
        $sSQL .= " and (placex.country_code IS NULL OR placex.country_code = '" . $sCountryCode . "' OR rank_address < 4)";
    }
    $sSQL .= " order by cached_rank_address desc,fromarea desc,distance asc,rank_search desc,namelength desc";
    //var_dump($sSQL);
    $aAddressLines = $oDB->getAll($sSQL);
    if (PEAR::IsError($aAddressLines)) {
        var_dump($aAddressLines);
        exit;
    }
    if ($bRaw) {
        return $aAddressLines;
    }
    $aClassType = getClassTypes();
    $iMinRank = 100;
    $aAddress = array();
    if ($sHouseNumber) {
        $aAddress['house_number'] = $sHouseNumber;
    }
    foreach ($aAddressLines as $aLine) {
        if (!$sCountryCode) {
            $sCountryCode = $aLine['country_code'];
        }
        if ($aLine['rank_address'] < $iMinRank) {
            $aTypeLabel = false;
            if (isset($aClassType[$aLine['class'] . ':' . $aLine['type'] . ':' . $aLine['admin_level']])) {
                $aTypeLabel = $aClassType[$aLine['class'] . ':' . $aLine['type'] . ':' . $aLine['admin_level']];
            } elseif (isset($aClassType[$aLine['class'] . ':' . $aLine['type']])) {
                $aTypeLabel = $aClassType[$aLine['class'] . ':' . $aLine['type']];
            } else {
                $aTypeLabel = array('simplelabel' => $aLine['class']);
            }
            if ($aTypeLabel && ($aLine['localname'] || $aLine['housenumber'])) {
                $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel']) ? $aTypeLabel['simplelabel'] : $aTypeLabel['label']);
                if (!isset($aAddress[$sTypeLabel]) && $aLine['localname']) {
                    $aAddress[$sTypeLabel] = $aLine['localname'] ? $aLine['localname'] : $aLine['housenumber'];
                }
            }
            $iMinRank = $aLine['rank_address'];
        }
    }
    if ($iMinRank > 4 && $sCountryCode) {
        $sSQL = "select get_name_by_language(country_name.name,{$sLanguagePrefArraySQL}) as name";
        $sSQL .= " from country_name where country_code = '{$sCountryCode}'";
        $sCountryName = $oDB->getOne($sSQL);
        if ($sCountryName) {
            $aAddress['country'] = $sCountryName;
        }
    }
    if ($sCountryCode) {
        $aAddress['country_code'] = $sCountryCode;
    }
    return $aAddress;
}
Example #21
0
 function lookup()
 {
     if (!$this->sQuery && !$this->aStructuredQuery) {
         return false;
     }
     $sLanguagePrefArraySQL = "ARRAY[" . join(',', array_map("getDBQuoted", $this->aLangPrefOrder)) . "]";
     $sCountryCodesSQL = false;
     if ($this->aCountryCodes && sizeof($this->aCountryCodes)) {
         $sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes));
     }
     $sQuery = $this->sQuery;
     // Conflicts between US state abreviations and various words for 'the' in different languages
     if (isset($this->aLangPrefOrder['name:en'])) {
         $sQuery = preg_replace('/(^|,)\\s*il\\s*(,|$)/', '\\1illinois\\2', $sQuery);
         $sQuery = preg_replace('/(^|,)\\s*al\\s*(,|$)/', '\\1alabama\\2', $sQuery);
         $sQuery = preg_replace('/(^|,)\\s*la\\s*(,|$)/', '\\1louisiana\\2', $sQuery);
     }
     // View Box SQL
     $sViewboxCentreSQL = false;
     $bBoundingBoxSearch = false;
     if ($this->aViewBox) {
         $fHeight = $this->aViewBox[0] - $this->aViewBox[2];
         $fWidth = $this->aViewBox[1] - $this->aViewBox[3];
         $aBigViewBox[0] = $this->aViewBox[0] + $fHeight;
         $aBigViewBox[2] = $this->aViewBox[2] - $fHeight;
         $aBigViewBox[1] = $this->aViewBox[1] + $fWidth;
         $aBigViewBox[3] = $this->aViewBox[3] - $fWidth;
         $this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(" . (double) $this->aViewBox[0] . "," . (double) $this->aViewBox[1] . "),ST_Point(" . (double) $this->aViewBox[2] . "," . (double) $this->aViewBox[3] . ")),4326)";
         $this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(" . (double) $aBigViewBox[0] . "," . (double) $aBigViewBox[1] . "),ST_Point(" . (double) $aBigViewBox[2] . "," . (double) $aBigViewBox[3] . ")),4326)";
         $bBoundingBoxSearch = $this->bBoundedSearch;
     }
     // Route SQL
     if ($this->aRoutePoints) {
         $sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
         $bFirst = true;
         foreach ($this->aRoutePoints as $aPoint) {
             if (!$bFirst) {
                 $sViewboxCentreSQL .= ",";
             }
             $sViewboxCentreSQL .= $aPoint[0] . ' ' . $aPoint[1];
             $bFirst = false;
         }
         $sViewboxCentreSQL .= ")'::geometry,4326)";
         $sSQL = "select st_buffer(" . $sViewboxCentreSQL . "," . (double) ($_GET['routewidth'] / 69) . ")";
         $this->sViewboxSmallSQL = $this->oDB->getOne($sSQL);
         if (PEAR::isError($this->sViewboxSmallSQL)) {
             failInternalError("Could not get small viewbox.", $sSQL, $this->sViewboxSmallSQL);
         }
         $this->sViewboxSmallSQL = "'" . $this->sViewboxSmallSQL . "'::geometry";
         $sSQL = "select st_buffer(" . $sViewboxCentreSQL . "," . (double) ($_GET['routewidth'] / 30) . ")";
         $this->sViewboxLargeSQL = $this->oDB->getOne($sSQL);
         if (PEAR::isError($this->sViewboxLargeSQL)) {
             failInternalError("Could not get large viewbox.", $sSQL, $this->sViewboxLargeSQL);
         }
         $this->sViewboxLargeSQL = "'" . $this->sViewboxLargeSQL . "'::geometry";
         $bBoundingBoxSearch = $this->bBoundedSearch;
     }
     // Do we have anything that looks like a lat/lon pair?
     if ($aLooksLike = looksLikeLatLonPair($sQuery)) {
         $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon']));
         $sQuery = $aLooksLike['query'];
     }
     $aSearchResults = array();
     if ($sQuery || $this->aStructuredQuery) {
         // Start with a blank search
         $aSearches = array(array('iSearchRank' => 0, 'iNamePhrase' => -1, 'sCountryCode' => false, 'aName' => array(), 'aAddress' => array(), 'aFullNameAddress' => array(), 'aNameNonSearch' => array(), 'aAddressNonSearch' => array(), 'sOperator' => '', 'aFeatureName' => array(), 'sClass' => '', 'sType' => '', 'sHouseNumber' => '', 'fLat' => '', 'fLon' => '', 'fRadius' => ''));
         // Do we have a radius search?
         $sNearPointSQL = false;
         if ($this->aNearPoint) {
             $sNearPointSQL = "ST_SetSRID(ST_Point(" . (double) $this->aNearPoint[1] . "," . (double) $this->aNearPoint[0] . "),4326)";
             $aSearches[0]['fLat'] = (double) $this->aNearPoint[0];
             $aSearches[0]['fLon'] = (double) $this->aNearPoint[1];
             $aSearches[0]['fRadius'] = (double) $this->aNearPoint[2];
         }
         // Any 'special' terms in the search?
         $bSpecialTerms = false;
         preg_match_all('/\\[(.*)=(.*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
         $aSpecialTerms = array();
         foreach ($aSpecialTermsRaw as $aSpecialTerm) {
             $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
             $aSpecialTerms[strtolower($aSpecialTerm[1])] = $aSpecialTerm[2];
         }
         preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
         $aSpecialTerms = array();
         if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity']) {
             $aSpecialTermsRaw[] = array('[' . $this->aStructuredQuery['amenity'] . ']', $this->aStructuredQuery['amenity']);
             unset($this->aStructuredQuery['amenity']);
         }
         foreach ($aSpecialTermsRaw as $aSpecialTerm) {
             $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
             $sToken = $this->oDB->getOne("select make_standard_name('" . $aSpecialTerm[1] . "') as string");
             $sSQL = 'select * from (select word_id,word_token, word, class, type, country_code, operator';
             $sSQL .= ' from word where word_token in (\' ' . $sToken . '\')) as x where (class is not null and class not in (\'place\')) or country_code is not null';
             if (CONST_Debug) {
                 var_Dump($sSQL);
             }
             $aSearchWords = $this->oDB->getAll($sSQL);
             $aNewSearches = array();
             foreach ($aSearches as $aSearch) {
                 foreach ($aSearchWords as $aSearchTerm) {
                     $aNewSearch = $aSearch;
                     if ($aSearchTerm['country_code']) {
                         $aNewSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
                         $aNewSearches[] = $aNewSearch;
                         $bSpecialTerms = true;
                     }
                     if ($aSearchTerm['class']) {
                         $aNewSearch['sClass'] = $aSearchTerm['class'];
                         $aNewSearch['sType'] = $aSearchTerm['type'];
                         $aNewSearches[] = $aNewSearch;
                         $bSpecialTerms = true;
                     }
                 }
             }
             $aSearches = $aNewSearches;
         }
         // Split query into phrases
         // Commas are used to reduce the search space by indicating where phrases split
         if ($this->aStructuredQuery) {
             $aPhrases = $this->aStructuredQuery;
             $bStructuredPhrases = true;
         } else {
             $aPhrases = explode(',', $sQuery);
             $bStructuredPhrases = false;
         }
         // Convert each phrase to standard form
         // Create a list of standard words
         // Get all 'sets' of words
         // Generate a complete list of all
         $aTokens = array();
         foreach ($aPhrases as $iPhrase => $sPhrase) {
             $aPhrase = $this->oDB->getRow("select make_standard_name('" . pg_escape_string($sPhrase) . "') as string");
             if (PEAR::isError($aPhrase)) {
                 userError("Illegal query string (not an UTF-8 string): " . $sPhrase);
                 if (CONST_Debug) {
                     var_dump($aPhrase);
                 }
                 exit;
             }
             if (trim($aPhrase['string'])) {
                 $aPhrases[$iPhrase] = $aPhrase;
                 $aPhrases[$iPhrase]['words'] = explode(' ', $aPhrases[$iPhrase]['string']);
                 $aPhrases[$iPhrase]['wordsets'] = getWordSets($aPhrases[$iPhrase]['words'], 0);
                 $aTokens = array_merge($aTokens, getTokensFromSets($aPhrases[$iPhrase]['wordsets']));
             } else {
                 unset($aPhrases[$iPhrase]);
             }
         }
         // Reindex phrases - we make assumptions later on that they are numerically keyed in order
         $aPhraseTypes = array_keys($aPhrases);
         $aPhrases = array_values($aPhrases);
         if (sizeof($aTokens)) {
             // Check which tokens we have, get the ID numbers
             $sSQL = 'select word_id,word_token, word, class, type, country_code, operator, search_name_count';
             $sSQL .= ' from word where word_token in (' . join(',', array_map("getDBQuoted", $aTokens)) . ')';
             if (CONST_Debug) {
                 var_Dump($sSQL);
             }
             $aValidTokens = array();
             if (sizeof($aTokens)) {
                 $aDatabaseWords = $this->oDB->getAll($sSQL);
             } else {
                 $aDatabaseWords = array();
             }
             if (PEAR::IsError($aDatabaseWords)) {
                 failInternalError("Could not get word tokens.", $sSQL, $aDatabaseWords);
             }
             $aPossibleMainWordIDs = array();
             $aWordFrequencyScores = array();
             foreach ($aDatabaseWords as $aToken) {
                 // Very special case - require 2 letter country param to match the country code found
                 if ($bStructuredPhrases && $aToken['country_code'] && !empty($this->aStructuredQuery['country']) && strlen($this->aStructuredQuery['country']) == 2 && strtolower($this->aStructuredQuery['country']) != $aToken['country_code']) {
                     continue;
                 }
                 if (isset($aValidTokens[$aToken['word_token']])) {
                     $aValidTokens[$aToken['word_token']][] = $aToken;
                 } else {
                     $aValidTokens[$aToken['word_token']] = array($aToken);
                 }
                 if (!$aToken['class'] && !$aToken['country_code']) {
                     $aPossibleMainWordIDs[$aToken['word_id']] = 1;
                 }
                 $aWordFrequencyScores[$aToken['word_id']] = $aToken['search_name_count'] + 1;
             }
             if (CONST_Debug) {
                 var_Dump($aPhrases, $aValidTokens);
             }
             // Try and calculate GB postcodes we might be missing
             foreach ($aTokens as $sToken) {
                 // Source of gb postcodes is now definitive - always use
                 if (preg_match('/^([A-Z][A-Z]?[0-9][0-9A-Z]? ?[0-9])([A-Z][A-Z])$/', strtoupper(trim($sToken)), $aData)) {
                     if (substr($aData[1], -2, 1) != ' ') {
                         $aData[0] = substr($aData[0], 0, strlen($aData[1]) - 1) . ' ' . substr($aData[0], strlen($aData[1]) - 1);
                         $aData[1] = substr($aData[1], 0, -1) . ' ' . substr($aData[1], -1, 1);
                     }
                     $aGBPostcodeLocation = gbPostcodeCalculate($aData[0], $aData[1], $aData[2], $this->oDB);
                     if ($aGBPostcodeLocation) {
                         $aValidTokens[$sToken] = $aGBPostcodeLocation;
                     }
                 } else {
                     if (!isset($aValidTokens[$sToken]) && preg_match('/^([0-9]{5}) [0-9]{4}$/', $sToken, $aData)) {
                         if (isset($aValidTokens[$aData[1]])) {
                             foreach ($aValidTokens[$aData[1]] as $aToken) {
                                 if (!$aToken['class']) {
                                     if (isset($aValidTokens[$sToken])) {
                                         $aValidTokens[$sToken][] = $aToken;
                                     } else {
                                         $aValidTokens[$sToken] = array($aToken);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             foreach ($aTokens as $sToken) {
                 // Unknown single word token with a number - assume it is a house number
                 if (!isset($aValidTokens[' ' . $sToken]) && strpos($sToken, ' ') === false && preg_match('/[0-9]/', $sToken)) {
                     $aValidTokens[' ' . $sToken] = array(array('class' => 'place', 'type' => 'house'));
                 }
             }
             // Any words that have failed completely?
             // TODO: suggestions
             // Start the search process
             $aResultPlaceIDs = array();
             $aGroupedSearches = $this->getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases);
             if ($this->bReverseInPlan) {
                 // Reverse phrase array and also reverse the order of the wordsets in
                 // the first and final phrase. Don't bother about phrases in the middle
                 // because order in the address doesn't matter.
                 $aPhrases = array_reverse($aPhrases);
                 $aPhrases[0]['wordsets'] = getInverseWordSets($aPhrases[0]['words'], 0);
                 if (sizeof($aPhrases) > 1) {
                     $aFinalPhrase = end($aPhrases);
                     $aPhrases[sizeof($aPhrases) - 1]['wordsets'] = getInverseWordSets($aFinalPhrase['words'], 0);
                 }
                 $aReverseGroupedSearches = $this->getGroupedSearches($aSearches, null, $aPhrases, $aValidTokens, $aWordFrequencyScores, false);
                 foreach ($aGroupedSearches as $aSearches) {
                     foreach ($aSearches as $aSearch) {
                         if ($aSearch['iSearchRank'] < $this->iMaxRank) {
                             if (!isset($aReverseGroupedSearches[$aSearch['iSearchRank']])) {
                                 $aReverseGroupedSearches[$aSearch['iSearchRank']] = array();
                             }
                             $aReverseGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
                         }
                     }
                 }
                 $aGroupedSearches = $aReverseGroupedSearches;
                 ksort($aGroupedSearches);
             }
         } else {
             // Re-group the searches by their score, junk anything over 20 as just not worth trying
             $aGroupedSearches = array();
             foreach ($aSearches as $aSearch) {
                 if ($aSearch['iSearchRank'] < $this->iMaxRank) {
                     if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) {
                         $aGroupedSearches[$aSearch['iSearchRank']] = array();
                     }
                     $aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
                 }
             }
             ksort($aGroupedSearches);
         }
         if (CONST_Debug) {
             var_Dump($aGroupedSearches);
         }
         if (CONST_Search_TryDroppedAddressTerms && sizeof($this->aStructuredQuery) > 0) {
             $aCopyGroupedSearches = $aGroupedSearches;
             foreach ($aCopyGroupedSearches as $iGroup => $aSearches) {
                 foreach ($aSearches as $iSearch => $aSearch) {
                     $aReductionsList = array($aSearch['aAddress']);
                     $iSearchRank = $aSearch['iSearchRank'];
                     while (sizeof($aReductionsList) > 0) {
                         $iSearchRank += 5;
                         if ($iSearchRank > iMaxRank) {
                             break 3;
                         }
                         $aNewReductionsList = array();
                         foreach ($aReductionsList as $aReductionsWordList) {
                             for ($iReductionWord = 0; $iReductionWord < sizeof($aReductionsWordList); $iReductionWord++) {
                                 $aReductionsWordListResult = array_merge(array_slice($aReductionsWordList, 0, $iReductionWord), array_slice($aReductionsWordList, $iReductionWord + 1));
                                 $aReverseSearch = $aSearch;
                                 $aSearch['aAddress'] = $aReductionsWordListResult;
                                 $aSearch['iSearchRank'] = $iSearchRank;
                                 $aGroupedSearches[$iSearchRank][] = $aReverseSearch;
                                 if (sizeof($aReductionsWordListResult) > 0) {
                                     $aNewReductionsList[] = $aReductionsWordListResult;
                                 }
                             }
                         }
                         $aReductionsList = $aNewReductionsList;
                     }
                 }
             }
             ksort($aGroupedSearches);
         }
         // Filter out duplicate searches
         $aSearchHash = array();
         foreach ($aGroupedSearches as $iGroup => $aSearches) {
             foreach ($aSearches as $iSearch => $aSearch) {
                 $sHash = serialize($aSearch);
                 if (isset($aSearchHash[$sHash])) {
                     unset($aGroupedSearches[$iGroup][$iSearch]);
                     if (sizeof($aGroupedSearches[$iGroup]) == 0) {
                         unset($aGroupedSearches[$iGroup]);
                     }
                 } else {
                     $aSearchHash[$sHash] = 1;
                 }
             }
         }
         if (CONST_Debug) {
             _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
         }
         $iGroupLoop = 0;
         $iQueryLoop = 0;
         foreach ($aGroupedSearches as $iGroupedRank => $aSearches) {
             $iGroupLoop++;
             foreach ($aSearches as $aSearch) {
                 $iQueryLoop++;
                 if (CONST_Debug) {
                     echo "<hr><b>Search Loop, group {$iGroupLoop}, loop {$iQueryLoop}</b>";
                 }
                 if (CONST_Debug) {
                     _debugDumpGroupedSearches(array($iGroupedRank => array($aSearch)), $aValidTokens);
                 }
                 // No location term?
                 if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['fLon']) {
                     if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber']) {
                         // Just looking for a country by code - look it up
                         if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) {
                             $sSQL = "select place_id from placex where calculated_country_code='" . $aSearch['sCountryCode'] . "' and rank_search = 4";
                             if ($sCountryCodesSQL) {
                                 $sSQL .= " and calculated_country_code in ({$sCountryCodesSQL})";
                             }
                             if ($bBoundingBoxSearch) {
                                 $sSQL .= " and _st_intersects({$this->sViewboxSmallSQL}, geometry)";
                             }
                             $sSQL .= " order by st_area(geometry) desc limit 1";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aPlaceIDs = $this->oDB->getCol($sSQL);
                         } else {
                             $aPlaceIDs = array();
                         }
                     } else {
                         if (!$bBoundingBoxSearch && !$aSearch['fLon']) {
                             continue;
                         }
                         if (!$aSearch['sClass']) {
                             continue;
                         }
                         $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_" . $aSearch['sClass'] . "_" . $aSearch['sType'] . "'";
                         if ($this->oDB->getOne($sSQL)) {
                             $sSQL = "select place_id from place_classtype_" . $aSearch['sClass'] . "_" . $aSearch['sType'] . " ct";
                             if ($sCountryCodesSQL) {
                                 $sSQL .= " join placex using (place_id)";
                             }
                             $sSQL .= " where st_contains({$this->sViewboxSmallSQL}, ct.centroid)";
                             if ($sCountryCodesSQL) {
                                 $sSQL .= " and calculated_country_code in ({$sCountryCodesSQL})";
                             }
                             if (sizeof($this->aExcludePlaceIDs)) {
                                 $sSQL .= " and place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                             }
                             if ($sViewboxCentreSQL) {
                                 $sSQL .= " order by st_distance({$sViewboxCentreSQL}, ct.centroid) asc";
                             }
                             $sSQL .= " limit {$this->iLimit}";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aPlaceIDs = $this->oDB->getCol($sSQL);
                             // If excluded place IDs are given, it is fair to assume that
                             // there have been results in the small box, so no further
                             // expansion in that case.
                             // Also don't expand if bounded results were requested.
                             if (!sizeof($aPlaceIDs) && !sizeof($this->aExcludePlaceIDs) && !$this->bBoundedSearch) {
                                 $sSQL = "select place_id from place_classtype_" . $aSearch['sClass'] . "_" . $aSearch['sType'] . " ct";
                                 if ($sCountryCodesSQL) {
                                     $sSQL .= " join placex using (place_id)";
                                 }
                                 $sSQL .= " where st_contains({$this->sViewboxLargeSQL}, ct.centroid)";
                                 if ($sCountryCodesSQL) {
                                     $sSQL .= " and calculated_country_code in ({$sCountryCodesSQL})";
                                 }
                                 if ($sViewboxCentreSQL) {
                                     $sSQL .= " order by st_distance({$sViewboxCentreSQL}, ct.centroid) asc";
                                 }
                                 $sSQL .= " limit {$this->iLimit}";
                                 if (CONST_Debug) {
                                     var_dump($sSQL);
                                 }
                                 $aPlaceIDs = $this->oDB->getCol($sSQL);
                             }
                         } else {
                             $sSQL = "select place_id from placex where class='" . $aSearch['sClass'] . "' and type='" . $aSearch['sType'] . "'";
                             $sSQL .= " and st_contains({$this->sViewboxSmallSQL}, geometry) and linked_place_id is null";
                             if ($sCountryCodesSQL) {
                                 $sSQL .= " and calculated_country_code in ({$sCountryCodesSQL})";
                             }
                             if ($sViewboxCentreSQL) {
                                 $sSQL .= " order by st_distance({$sViewboxCentreSQL}, centroid) asc";
                             }
                             $sSQL .= " limit {$this->iLimit}";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aPlaceIDs = $this->oDB->getCol($sSQL);
                         }
                     }
                 } else {
                     $aPlaceIDs = array();
                     // First we need a position, either aName or fLat or both
                     $aTerms = array();
                     $aOrder = array();
                     if ($aSearch['sHouseNumber'] && sizeof($aSearch['aAddress'])) {
                         $sHouseNumberRegex = '\\\\m' . $aSearch['sHouseNumber'] . '\\\\M';
                         $aOrder[] = "exists(select place_id from placex where parent_place_id = search_name.place_id and transliteration(housenumber) ~* E'" . $sHouseNumberRegex . "' limit 1) desc";
                     }
                     // TODO: filter out the pointless search terms (2 letter name tokens and less)
                     // they might be right - but they are just too darned expensive to run
                     if (sizeof($aSearch['aName'])) {
                         $aTerms[] = "name_vector @> ARRAY[" . join($aSearch['aName'], ",") . "]";
                     }
                     if (sizeof($aSearch['aNameNonSearch'])) {
                         $aTerms[] = "array_cat(name_vector,ARRAY[]::integer[]) @> ARRAY[" . join($aSearch['aNameNonSearch'], ",") . "]";
                     }
                     if (sizeof($aSearch['aAddress']) && $aSearch['aName'] != $aSearch['aAddress']) {
                         // For infrequent name terms disable index usage for address
                         if (CONST_Search_NameOnlySearchFrequencyThreshold && sizeof($aSearch['aName']) == 1 && $aWordFrequencyScores[$aSearch['aName'][reset($aSearch['aName'])]] < CONST_Search_NameOnlySearchFrequencyThreshold) {
                             $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[" . join(array_merge($aSearch['aAddress'], $aSearch['aAddressNonSearch']), ",") . "]";
                         } else {
                             $aTerms[] = "nameaddress_vector @> ARRAY[" . join($aSearch['aAddress'], ",") . "]";
                             if (sizeof($aSearch['aAddressNonSearch'])) {
                                 $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[" . join($aSearch['aAddressNonSearch'], ",") . "]";
                             }
                         }
                     }
                     if ($aSearch['sCountryCode']) {
                         $aTerms[] = "country_code = '" . pg_escape_string($aSearch['sCountryCode']) . "'";
                     }
                     if ($aSearch['sHouseNumber']) {
                         $aTerms[] = "address_rank between 16 and 27";
                     } else {
                         if ($this->iMinAddressRank > 0) {
                             $aTerms[] = "address_rank >= " . $this->iMinAddressRank;
                         }
                         if ($this->iMaxAddressRank < 30) {
                             $aTerms[] = "address_rank <= " . $this->iMaxAddressRank;
                         }
                     }
                     if ($aSearch['fLon'] && $aSearch['fLat']) {
                         $aTerms[] = "ST_DWithin(centroid, ST_SetSRID(ST_Point(" . $aSearch['fLon'] . "," . $aSearch['fLat'] . "),4326), " . $aSearch['fRadius'] . ")";
                         $aOrder[] = "ST_Distance(centroid, ST_SetSRID(ST_Point(" . $aSearch['fLon'] . "," . $aSearch['fLat'] . "),4326)) ASC";
                     }
                     if (sizeof($this->aExcludePlaceIDs)) {
                         $aTerms[] = "place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                     }
                     if ($sCountryCodesSQL) {
                         $aTerms[] = "country_code in ({$sCountryCodesSQL})";
                     }
                     if ($bBoundingBoxSearch) {
                         $aTerms[] = "centroid && {$this->sViewboxSmallSQL}";
                     }
                     if ($sNearPointSQL) {
                         $aOrder[] = "ST_Distance({$sNearPointSQL}, centroid) asc";
                     }
                     if ($aSearch['sHouseNumber']) {
                         $sImportanceSQL = '- abs(26 - address_rank) + 3';
                     } else {
                         $sImportanceSQL = '(case when importance = 0 OR importance IS NULL then 0.75-(search_rank::float/40) else importance end)';
                     }
                     if ($this->sViewboxSmallSQL) {
                         $sImportanceSQL .= " * case when ST_Contains({$this->sViewboxSmallSQL}, centroid) THEN 1 ELSE 0.5 END";
                     }
                     if ($this->sViewboxLargeSQL) {
                         $sImportanceSQL .= " * case when ST_Contains({$this->sViewboxLargeSQL}, centroid) THEN 1 ELSE 0.5 END";
                     }
                     $aOrder[] = "{$sImportanceSQL} DESC";
                     if (sizeof($aSearch['aFullNameAddress'])) {
                         $sExactMatchSQL = '(select count(*) from (select unnest(ARRAY[' . join($aSearch['aFullNameAddress'], ",") . ']) INTERSECT select unnest(nameaddress_vector))s) as exactmatch';
                         $aOrder[] = 'exactmatch DESC';
                     } else {
                         $sExactMatchSQL = '0::int as exactmatch';
                     }
                     if (sizeof($aTerms)) {
                         $sSQL = "select place_id, ";
                         $sSQL .= $sExactMatchSQL;
                         $sSQL .= " from search_name";
                         $sSQL .= " where " . join(' and ', $aTerms);
                         $sSQL .= " order by " . join(', ', $aOrder);
                         if ($aSearch['sHouseNumber'] || $aSearch['sClass']) {
                             $sSQL .= " limit 20";
                         } elseif (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && $aSearch['sClass']) {
                             $sSQL .= " limit 1";
                         } else {
                             $sSQL .= " limit " . $this->iLimit;
                         }
                         if (CONST_Debug) {
                             var_dump($sSQL);
                         }
                         $aViewBoxPlaceIDs = $this->oDB->getAll($sSQL);
                         if (PEAR::IsError($aViewBoxPlaceIDs)) {
                             failInternalError("Could not get places for search terms.", $sSQL, $aViewBoxPlaceIDs);
                         }
                         //var_dump($aViewBoxPlaceIDs);
                         // Did we have an viewbox matches?
                         $aPlaceIDs = array();
                         $bViewBoxMatch = false;
                         foreach ($aViewBoxPlaceIDs as $aViewBoxRow) {
                             //if ($bViewBoxMatch == 1 && $aViewBoxRow['in_small'] == 'f') break;
                             //if ($bViewBoxMatch == 2 && $aViewBoxRow['in_large'] == 'f') break;
                             //if ($aViewBoxRow['in_small'] == 't') $bViewBoxMatch = 1;
                             //else if ($aViewBoxRow['in_large'] == 't') $bViewBoxMatch = 2;
                             $aPlaceIDs[] = $aViewBoxRow['place_id'];
                             $this->exactMatchCache[$aViewBoxRow['place_id']] = $aViewBoxRow['exactmatch'];
                         }
                     }
                     //var_Dump($aPlaceIDs);
                     //exit;
                     if ($aSearch['sHouseNumber'] && sizeof($aPlaceIDs)) {
                         $aRoadPlaceIDs = $aPlaceIDs;
                         $sPlaceIDs = join(',', $aPlaceIDs);
                         // Now they are indexed look for a house attached to a street we found
                         $sHouseNumberRegex = '\\\\m' . $aSearch['sHouseNumber'] . '\\\\M';
                         $sSQL = "select place_id from placex where parent_place_id in (" . $sPlaceIDs . ") and transliteration(housenumber) ~* E'" . $sHouseNumberRegex . "'";
                         if (sizeof($this->aExcludePlaceIDs)) {
                             $sSQL .= " and place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                         }
                         $sSQL .= " limit {$this->iLimit}";
                         if (CONST_Debug) {
                             var_dump($sSQL);
                         }
                         $aPlaceIDs = $this->oDB->getCol($sSQL);
                         // If not try the aux fallback table
                         if (!sizeof($aPlaceIDs)) {
                             $sSQL = "select place_id from location_property_aux where parent_place_id in (" . $sPlaceIDs . ") and housenumber = '" . pg_escape_string($aSearch['sHouseNumber']) . "'";
                             if (sizeof($this->aExcludePlaceIDs)) {
                                 $sSQL .= " and place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                             }
                             //$sSQL .= " limit $this->iLimit";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aPlaceIDs = $this->oDB->getCol($sSQL);
                         }
                         if (!sizeof($aPlaceIDs)) {
                             $sSQL = "select place_id from location_property_tiger where parent_place_id in (" . $sPlaceIDs . ") and housenumber = '" . pg_escape_string($aSearch['sHouseNumber']) . "'";
                             if (sizeof($this->aExcludePlaceIDs)) {
                                 $sSQL .= " and place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                             }
                             //$sSQL .= " limit $this->iLimit";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aPlaceIDs = $this->oDB->getCol($sSQL);
                         }
                         // Fallback to the road
                         if (!sizeof($aPlaceIDs) && preg_match('/[0-9]+/', $aSearch['sHouseNumber'])) {
                             $aPlaceIDs = $aRoadPlaceIDs;
                         }
                     }
                     if ($aSearch['sClass'] && sizeof($aPlaceIDs)) {
                         $sPlaceIDs = join(',', $aPlaceIDs);
                         $aClassPlaceIDs = array();
                         if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'name') {
                             // If they were searching for a named class (i.e. 'Kings Head pub') then we might have an extra match
                             $sSQL = "select place_id from placex where place_id in ({$sPlaceIDs}) and class='" . $aSearch['sClass'] . "' and type='" . $aSearch['sType'] . "'";
                             $sSQL .= " and linked_place_id is null";
                             if ($sCountryCodesSQL) {
                                 $sSQL .= " and calculated_country_code in ({$sCountryCodesSQL})";
                             }
                             $sSQL .= " order by rank_search asc limit {$this->iLimit}";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $aClassPlaceIDs = $this->oDB->getCol($sSQL);
                         }
                         if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'near') {
                             $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_" . $aSearch['sClass'] . "_" . $aSearch['sType'] . "'";
                             $bCacheTable = $this->oDB->getOne($sSQL);
                             $sSQL = "select min(rank_search) from placex where place_id in ({$sPlaceIDs})";
                             if (CONST_Debug) {
                                 var_dump($sSQL);
                             }
                             $this->iMaxRank = (int) $this->oDB->getOne($sSQL);
                             // For state / country level searches the normal radius search doesn't work very well
                             $sPlaceGeom = false;
                             if ($this->iMaxRank < 9 && $bCacheTable) {
                                 // Try and get a polygon to search in instead
                                 $sSQL = "select geometry from placex where place_id in ({$sPlaceIDs}) and rank_search < {$this->iMaxRank} + 5 and st_geometrytype(geometry) in ('ST_Polygon','ST_MultiPolygon') order by rank_search asc limit 1";
                                 if (CONST_Debug) {
                                     var_dump($sSQL);
                                 }
                                 $sPlaceGeom = $this->oDB->getOne($sSQL);
                             }
                             if ($sPlaceGeom) {
                                 $sPlaceIDs = false;
                             } else {
                                 $this->iMaxRank += 5;
                                 $sSQL = "select place_id from placex where place_id in ({$sPlaceIDs}) and rank_search < {$this->iMaxRank}";
                                 if (CONST_Debug) {
                                     var_dump($sSQL);
                                 }
                                 $aPlaceIDs = $this->oDB->getCol($sSQL);
                                 $sPlaceIDs = join(',', $aPlaceIDs);
                             }
                             if ($sPlaceIDs || $sPlaceGeom) {
                                 $fRange = 0.01;
                                 if ($bCacheTable) {
                                     // More efficient - can make the range bigger
                                     $fRange = 0.05;
                                     $sOrderBySQL = '';
                                     if ($sNearPointSQL) {
                                         $sOrderBySQL = "ST_Distance({$sNearPointSQL}, l.centroid)";
                                     } else {
                                         if ($sPlaceIDs) {
                                             $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)";
                                         } else {
                                             if ($sPlaceGeom) {
                                                 $sOrderBysSQL = "ST_Distance(st_centroid('" . $sPlaceGeom . "'), l.centroid)";
                                             }
                                         }
                                     }
                                     $sSQL = "select distinct l.place_id" . ($sOrderBySQL ? ',' . $sOrderBySQL : '') . " from place_classtype_" . $aSearch['sClass'] . "_" . $aSearch['sType'] . " as l";
                                     if ($sCountryCodesSQL) {
                                         $sSQL .= " join placex as lp using (place_id)";
                                     }
                                     if ($sPlaceIDs) {
                                         $sSQL .= ",placex as f where ";
                                         $sSQL .= "f.place_id in ({$sPlaceIDs}) and ST_DWithin(l.centroid, f.centroid, {$fRange}) ";
                                     }
                                     if ($sPlaceGeom) {
                                         $sSQL .= " where ";
                                         $sSQL .= "ST_Contains('" . $sPlaceGeom . "', l.centroid) ";
                                     }
                                     if (sizeof($this->aExcludePlaceIDs)) {
                                         $sSQL .= " and l.place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                                     }
                                     if ($sCountryCodesSQL) {
                                         $sSQL .= " and lp.calculated_country_code in ({$sCountryCodesSQL})";
                                     }
                                     if ($sOrderBySQL) {
                                         $sSQL .= "order by " . $sOrderBySQL . " asc";
                                     }
                                     if ($this->iOffset) {
                                         $sSQL .= " offset {$this->iOffset}";
                                     }
                                     $sSQL .= " limit {$this->iLimit}";
                                     if (CONST_Debug) {
                                         var_dump($sSQL);
                                     }
                                     $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL));
                                 } else {
                                     if (isset($aSearch['fRadius']) && $aSearch['fRadius']) {
                                         $fRange = $aSearch['fRadius'];
                                     }
                                     $sOrderBySQL = '';
                                     if ($sNearPointSQL) {
                                         $sOrderBySQL = "ST_Distance({$sNearPointSQL}, l.geometry)";
                                     } else {
                                         $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)";
                                     }
                                     $sSQL = "select distinct l.place_id" . ($sOrderBysSQL ? ',' . $sOrderBysSQL : '') . " from placex as l,placex as f where ";
                                     $sSQL .= "f.place_id in ( {$sPlaceIDs}) and ST_DWithin(l.geometry, f.centroid, {$fRange}) ";
                                     $sSQL .= "and l.class='" . $aSearch['sClass'] . "' and l.type='" . $aSearch['sType'] . "' ";
                                     if (sizeof($this->aExcludePlaceIDs)) {
                                         $sSQL .= " and l.place_id not in (" . join(',', $this->aExcludePlaceIDs) . ")";
                                     }
                                     if ($sCountryCodesSQL) {
                                         $sSQL .= " and l.calculated_country_code in ({$sCountryCodesSQL})";
                                     }
                                     if ($sOrderBy) {
                                         $sSQL .= "order by " . $OrderBysSQL . " asc";
                                     }
                                     if ($this->iOffset) {
                                         $sSQL .= " offset {$this->iOffset}";
                                     }
                                     $sSQL .= " limit {$this->iLimit}";
                                     if (CONST_Debug) {
                                         var_dump($sSQL);
                                     }
                                     $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL));
                                 }
                             }
                         }
                         $aPlaceIDs = $aClassPlaceIDs;
                     }
                 }
                 if (PEAR::IsError($aPlaceIDs)) {
                     failInternalError("Could not get place IDs from tokens.", $sSQL, $aPlaceIDs);
                 }
                 if (CONST_Debug) {
                     echo "<br><b>Place IDs:</b> ";
                     var_Dump($aPlaceIDs);
                 }
                 foreach ($aPlaceIDs as $iPlaceID) {
                     $aResultPlaceIDs[$iPlaceID] = $iPlaceID;
                 }
                 if ($iQueryLoop > 20) {
                     break;
                 }
             }
             if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs) && ($this->iMinAddressRank != 0 || $this->iMaxAddressRank != 30)) {
                 // Need to verify passes rank limits before dropping out of the loop (yuk!)
                 $sSQL = "select place_id from placex where place_id in (" . join(',', $aResultPlaceIDs) . ") ";
                 $sSQL .= "and (placex.rank_address between {$this->iMinAddressRank} and {$this->iMaxAddressRank} ";
                 if (14 >= $this->iMinAddressRank && 14 <= $this->iMaxAddressRank) {
                     $sSQL .= " OR (extratags->'place') = 'city'";
                 }
                 if ($this->aAddressRankList) {
                     $sSQL .= " OR placex.rank_address in (" . join(',', $this->aAddressRankList) . ")";
                 }
                 $sSQL .= ") UNION select place_id from location_property_tiger where place_id in (" . join(',', $aResultPlaceIDs) . ") ";
                 $sSQL .= "and (30 between {$this->iMinAddressRank} and {$this->iMaxAddressRank} ";
                 if ($this->aAddressRankList) {
                     $sSQL .= " OR 30 in (" . join(',', $this->aAddressRankList) . ")";
                 }
                 $sSQL .= ")";
                 if (CONST_Debug) {
                     var_dump($sSQL);
                 }
                 $aResultPlaceIDs = $this->oDB->getCol($sSQL);
             }
             //exit;
             if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) {
                 break;
             }
             if ($iGroupLoop > 4) {
                 break;
             }
             if ($iQueryLoop > 30) {
                 break;
             }
         }
         // Did we find anything?
         if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) {
             $aSearchResults = $this->getDetails($aResultPlaceIDs);
         }
     } else {
         // Just interpret as a reverse geocode
         $iPlaceID = geocodeReverse((double) $this->aNearPoint[0], (double) $this->aNearPoint[1]);
         if ($iPlaceID) {
             $aSearchResults = $this->getDetails(array($iPlaceID));
         } else {
             $aSearchResults = array();
         }
     }
     // No results? Done
     if (!sizeof($aSearchResults)) {
         if ($this->bFallback) {
             if ($this->fallbackStructuredQuery()) {
                 return $this->lookup();
             }
         }
         return array();
     }
     $aClassType = getClassTypesWithImportance();
     $aRecheckWords = preg_split('/\\b[\\s,\\-]*/u', $sQuery);
     foreach ($aRecheckWords as $i => $sWord) {
         if (!preg_match('/\\pL/', $sWord)) {
             unset($aRecheckWords[$i]);
         }
     }
     if (CONST_Debug) {
         echo '<i>Recheck words:<\\i>';
         var_dump($aRecheckWords);
     }
     foreach ($aSearchResults as $iResNum => $aResult) {
         // Default
         $fDiameter = 0.0001;
         if (isset($aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['defdiameter']) && $aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['defdiameter']) {
             $fDiameter = $aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['defdiameter'];
         } elseif (isset($aClassType[$aResult['class'] . ':' . $aResult['type']]['defdiameter']) && $aClassType[$aResult['class'] . ':' . $aResult['type']]['defdiameter']) {
             $fDiameter = $aClassType[$aResult['class'] . ':' . $aResult['type']]['defdiameter'];
         }
         $fRadius = $fDiameter / 2;
         if (CONST_Search_AreaPolygons) {
             // Get the bounding box and outline polygon
             $sSQL = "select place_id,0 as numfeatures,st_area(geometry) as area,";
             $sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
             $sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
             $sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
             if ($this->bIncludePolygonAsGeoJSON) {
                 $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson";
             }
             if ($this->bIncludePolygonAsKML) {
                 $sSQL .= ",ST_AsKML(geometry) as askml";
             }
             if ($this->bIncludePolygonAsSVG) {
                 $sSQL .= ",ST_AsSVG(geometry) as assvg";
             }
             if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) {
                 $sSQL .= ",ST_AsText(geometry) as astext";
             }
             $sFrom = " from placex where place_id = " . $aResult['place_id'];
             if ($this->fPolygonSimplificationThreshold > 0) {
                 $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry," . $this->fPolygonSimplificationThreshold . ") as geometry" . $sFrom . ") as plx";
             } else {
                 $sSQL .= $sFrom;
             }
             $aPointPolygon = $this->oDB->getRow($sSQL);
             if (PEAR::IsError($aPointPolygon)) {
                 failInternalError("Could not get outline.", $sSQL, $aPointPolygon);
             }
             if ($aPointPolygon['place_id']) {
                 if ($this->bIncludePolygonAsGeoJSON) {
                     $aResult['asgeojson'] = $aPointPolygon['asgeojson'];
                 }
                 if ($this->bIncludePolygonAsKML) {
                     $aResult['askml'] = $aPointPolygon['askml'];
                 }
                 if ($this->bIncludePolygonAsSVG) {
                     $aResult['assvg'] = $aPointPolygon['assvg'];
                 }
                 if ($this->bIncludePolygonAsText) {
                     $aResult['astext'] = $aPointPolygon['astext'];
                 }
                 if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null) {
                     $aResult['lat'] = $aPointPolygon['centrelat'];
                     $aResult['lon'] = $aPointPolygon['centrelon'];
                 }
                 if ($this->bIncludePolygonAsPoints) {
                     // Translate geometry string to point array
                     if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#', $aPointPolygon['astext'], $aMatch)) {
                         preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
                     } elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#', $aPointPolygon['astext'], $aMatch)) {
                         preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
                     } elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#', $aPointPolygon['astext'], $aMatch)) {
                         $iSteps = max(8, min(100, $fRadius * 40000 ^ 2));
                         $fStepSize = 2 * pi() / $iSteps;
                         $aPolyPoints = array();
                         for ($f = 0; $f < 2 * pi(); $f += $fStepSize) {
                             $aPolyPoints[] = array('', $aMatch[1] + $fRadius * sin($f), $aMatch[2] + $fRadius * cos($f));
                         }
                     }
                 }
                 // Output data suitable for display (points and a bounding box)
                 if ($this->bIncludePolygonAsPoints && isset($aPolyPoints)) {
                     $aResult['aPolyPoints'] = array();
                     foreach ($aPolyPoints as $aPoint) {
                         $aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
                     }
                 }
                 if (abs($aPointPolygon['minlat'] - $aPointPolygon['maxlat']) < 1.0E-7) {
                     $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
                     $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
                 }
                 if (abs($aPointPolygon['minlon'] - $aPointPolygon['maxlon']) < 1.0E-7) {
                     $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
                     $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
                 }
                 $aResult['aBoundingBox'] = array((string) $aPointPolygon['minlat'], (string) $aPointPolygon['maxlat'], (string) $aPointPolygon['minlon'], (string) $aPointPolygon['maxlon']);
             }
         }
         if ($aResult['extra_place'] == 'city') {
             $aResult['class'] = 'place';
             $aResult['type'] = 'city';
             $aResult['rank_search'] = 16;
         }
         if (!isset($aResult['aBoundingBox'])) {
             $iSteps = max(8, min(100, $fRadius * 3.14 * 100000));
             $fStepSize = 2 * pi() / $iSteps;
             $aPointPolygon['minlat'] = $aResult['lat'] - $fRadius;
             $aPointPolygon['maxlat'] = $aResult['lat'] + $fRadius;
             $aPointPolygon['minlon'] = $aResult['lon'] - $fRadius;
             $aPointPolygon['maxlon'] = $aResult['lon'] + $fRadius;
             // Output data suitable for display (points and a bounding box)
             if ($this->bIncludePolygonAsPoints) {
                 $aPolyPoints = array();
                 for ($f = 0; $f < 2 * pi(); $f += $fStepSize) {
                     $aPolyPoints[] = array('', $aResult['lon'] + $fRadius * sin($f), $aResult['lat'] + $fRadius * cos($f));
                 }
                 $aResult['aPolyPoints'] = array();
                 foreach ($aPolyPoints as $aPoint) {
                     $aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
                 }
             }
             $aResult['aBoundingBox'] = array((string) $aPointPolygon['minlat'], (string) $aPointPolygon['maxlat'], (string) $aPointPolygon['minlon'], (string) $aPointPolygon['maxlon']);
         }
         // Is there an icon set for this type of result?
         if (isset($aClassType[$aResult['class'] . ':' . $aResult['type']]['icon']) && $aClassType[$aResult['class'] . ':' . $aResult['type']]['icon']) {
             $aResult['icon'] = CONST_Website_BaseURL . 'images/mapicons/' . $aClassType[$aResult['class'] . ':' . $aResult['type']]['icon'] . '.p.20.png';
         }
         if (isset($aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['label']) && $aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['label']) {
             $aResult['label'] = $aClassType[$aResult['class'] . ':' . $aResult['type'] . ':' . $aResult['admin_level']]['label'];
         } elseif (isset($aClassType[$aResult['class'] . ':' . $aResult['type']]['label']) && $aClassType[$aResult['class'] . ':' . $aResult['type']]['label']) {
             $aResult['label'] = $aClassType[$aResult['class'] . ':' . $aResult['type']]['label'];
         }
         if ($this->bIncludeAddressDetails) {
             $aResult['address'] = getAddressDetails($this->oDB, $sLanguagePrefArraySQL, $aResult['place_id'], $aResult['country_code']);
             if ($aResult['extra_place'] == 'city' && !isset($aResult['address']['city'])) {
                 $aResult['address'] = array_merge(array('city' => array_shift(array_values($aResult['address']))), $aResult['address']);
             }
         }
         if ($this->bIncludeExtraTags) {
             if ($aResult['extra']) {
                 $aResult['sExtraTags'] = json_decode($aResult['extra']);
             } else {
                 $aResult['sExtraTags'] = (object) array();
             }
         }
         if ($this->bIncludeNameDetails) {
             if ($aResult['names']) {
                 $aResult['sNameDetails'] = json_decode($aResult['names']);
             } else {
                 $aResult['sNameDetails'] = (object) array();
             }
         }
         // Adjust importance for the number of exact string matches in the result
         $aResult['importance'] = max(0.001, $aResult['importance']);
         $iCountWords = 0;
         $sAddress = $aResult['langaddress'];
         foreach ($aRecheckWords as $i => $sWord) {
             if (stripos($sAddress, $sWord) !== false) {
                 $iCountWords++;
                 if (preg_match("/(^|,)\\s*" . preg_quote($sWord, '/') . "\\s*(,|\$)/", $sAddress)) {
                     $iCountWords += 0.1;
                 }
             }
         }
         $aResult['importance'] = $aResult['importance'] + $iCountWords * 0.1;
         // 0.1 is a completely arbitrary number but something in the range 0.1 to 0.5 would seem right
         $aResult['name'] = $aResult['langaddress'];
         // secondary ordering (for results with same importance (the smaller the better):
         //   - approximate importance of address parts
         $aResult['foundorder'] = -$aResult['addressimportance'] / 10;
         //   - number of exact matches from the query
         if (isset($this->exactMatchCache[$aResult['place_id']])) {
             $aResult['foundorder'] -= $this->exactMatchCache[$aResult['place_id']];
         } else {
             if (isset($this->exactMatchCache[$aResult['parent_place_id']])) {
                 $aResult['foundorder'] -= $this->exactMatchCache[$aResult['parent_place_id']];
             }
         }
         //  - importance of the class/type
         if (isset($aClassType[$aResult['class'] . ':' . $aResult['type']]['importance']) && $aClassType[$aResult['class'] . ':' . $aResult['type']]['importance']) {
             $aResult['foundorder'] += 0.0001 * $aClassType[$aResult['class'] . ':' . $aResult['type']]['importance'];
         } else {
             $aResult['foundorder'] += 0.01;
         }
         if (CONST_Debug) {
             var_dump($aResult);
         }
         $aSearchResults[$iResNum] = $aResult;
     }
     uasort($aSearchResults, 'byImportance');
     $aOSMIDDone = array();
     $aClassTypeNameDone = array();
     $aToFilter = $aSearchResults;
     $aSearchResults = array();
     $bFirst = true;
     foreach ($aToFilter as $iResNum => $aResult) {
         $this->aExcludePlaceIDs[$aResult['place_id']] = $aResult['place_id'];
         if ($bFirst) {
             $fLat = $aResult['lat'];
             $fLon = $aResult['lon'];
             if (isset($aResult['zoom'])) {
                 $iZoom = $aResult['zoom'];
             }
             $bFirst = false;
         }
         if (!$this->bDeDupe || !isset($aOSMIDDone[$aResult['osm_type'] . $aResult['osm_id']]) && !isset($aClassTypeNameDone[$aResult['osm_type'] . $aResult['class'] . $aResult['type'] . $aResult['name'] . $aResult['admin_level']])) {
             $aOSMIDDone[$aResult['osm_type'] . $aResult['osm_id']] = true;
             $aClassTypeNameDone[$aResult['osm_type'] . $aResult['class'] . $aResult['type'] . $aResult['name'] . $aResult['admin_level']] = true;
             $aSearchResults[] = $aResult;
         }
         // Absolute limit on number of results
         if (sizeof($aSearchResults) >= $this->iFinalLimit) {
             break;
         }
     }
     return $aSearchResults;
 }
Example #22
0
  function UltraMail( $to, 
                      $subject, 
                      $message, 
                      $additional_headers = '', 
                      $additional_parameters = '') 
  { 
    global $MailBoxs, $UltraMailError; 

    $UM_StFrom = ''; 

    ##---------------------------------------     
    ## Converte o HEADER de STRING para ARRAY 
    ##---------------------------------------     
    $Aux_headers = 
      str_replace("\r", '', $additional_headers); 
    $Aux_headers = split("\n", $Aux_headers); 
    $headers = array(); 
    foreach ($Aux_headers as $Aux_header) 
    { 
      if ( ereg( '^([^:]+):([^:]+)$', $Aux_header, $regs ) ) 
      { 
        $headers[ $regs[1] ] = $regs[2]; 
      } 
    } 
    ##---------------------------------------     

     
    ##--------------------------------------------------     
    ## Localiza os dados do MailBox que enviará o e-mail 
    ##--------------------------------------------------     
     
    # Caso o usuário não tenha configurado um FROM 
    # utilizar sempre o primeiro 
    if ( empty( $headers['From'] ) ) 
    { 
      if ( !Empty($MailBox['StName']) ) 
      { 
        $headers['From'] = 
          $MailBoxs[0]['StName'] . 
          " <{$MailBoxs[0]['StEMail']}>"; 
      } 
      else 
      { 
        $headers['From'] = $MailBoxs[0]['StEMail']; 
      } 
      $UM_StName     = $MailBoxs[0]['StName']; 
      $UM_StFrom     = $MailBoxs[0]['StEMail']; 
      $UM_StUser     = $MailBoxs[0]['StUser']; 
      $UM_StPassword = $MailBoxs[0]['StPassword']; 
      $UM_StServer   = $MailBoxs[0]['StSMTPServer']; 
    } 

    # Caso exista o FROM procurar os 
    # dados do MailBox do mesmo 
    else 
    { 
      if ( eregi( '<?([^<>, ]+\@[^<>, ]+)>?', 
                  $headers['From'], $regs ) ) 
      { 
        $EMailDeEnvio = $regs[1]; 
      } 
      else 
      { 
        print "E-mail inválido: $to<BR>\n"; 
        exit; 
      } 
     
      foreach ($MailBoxs as $MailBox) 
      { 
        if ($MailBox['StEMail'] == $EMailDeEnvio) 
        { 
          $UM_StName     = $MailBox['StName']; 
          $UM_StFrom     = $MailBox['StEMail']; 
          $UM_StUser     = $MailBox['StUser']; 
          $UM_StPassword = $MailBox['StPassword']; 
          $UM_StServer   = $MailBox['StSMTPServer']; 
        } 
      } 
       
      if ( Empty($UM_StFrom) ) 
      { 

        if ( !Empty($MailBox['StName']) ) 
        { 
          $headers['From'] = $MailBoxs[0]['StName'] . " <{$MailBoxs[0]['StEMail']}>"; 
        } 
        else 
        { 
          $headers['From'] = $MailBoxs[0]['StEMail']; 
        } 

        $UM_StName     = $MailBoxs[0]['StName']; 
        $UM_StFrom     = $MailBoxs[0]['StEMail']; 
        $UM_StUser     = $MailBoxs[0]['StUser']; 
        $UM_StPassword = $MailBoxs[0]['StPassword']; 
        $UM_StServer   = $MailBoxs[0]['StSMTPServer']; 
      } 
    }   
    ##--------------------------------------------------     
     

    ##------------------------------------------------ 
    ## Configura as varíaveis necessárias para o envio    
    ##------------------------------------------------ 
    $headers['To']      = $to; 
    $headers['Subject'] = $subject; 

    $recipients[0] = $to; 

    if ($headers['Cc']) 
    { 
      array_push($recipients, $headers['Cc']); 
    } 
       
    if ($headers['Bcc']) 
    { 
      array_push($recipients, $headers['Bcc']); 
    } 
       
    $params = 
      array ( 
        'auth' => true, # SMTP requer autenticação. 
        'host' => $UM_StServer, # Servidor SMTP 
        'username' => $UM_StUser, # Usuário do SMTP 
        'password' => $UM_StPassword # Senha do seu MailBox. 
      ); 
    ##------------------------------------------------ 


    ##------------------------------------ 
    ## Envio o e-mail de forma autenticada    
    ##------------------------------------ 

    # Define o método de envio. 
    # Queremos 'smtp'. OBRIGATÓRIO. 
    $mail_object =& Mail::factory('smtp', $params); 
    if (PEAR::IsError($mail_object)) 
    { 
      $UltraMailError = $mail_object->getMessage(); 
      return FALSE; 
    }    
     

    # Envia o email. Se não ocorrer erro retorna TRUE, 
    # caso contrário retorna um objeto PEAR_Error. 
    # Para ler a mensagem de erro use o método getMessage(). 
    $result = 
      $mail_object->send($recipients, $headers, $message); 
    if (PEAR::IsError($result)) 
    { 
      $UltraMailError = $result->getMessage(); 
      return FALSE; 
    }    
    else 
    { 
      return TRUE; 
    }    
    ##------------------------------------ 

  }