root/kladr/addr_suggest.php

Revision 65, 15.5 kB (checked in by teiko, 3 years ago)

небольшие исправления

Line 
1 <?php define('_VALID_MOS',1);require_once('include/protects.php');require_once('globals.php');require_once('configuration.php');require_once('include/minimambo.php');require_once('include/database.php');require_once('include/JsHttpRequest.php');// -------------------------------------------------------------------------$database  = new database($config_db_host,$config_db_user,$config_db_pass,$config_db_name,'');$JsHttpRequest =& new JsHttpRequest('utf-8');// -------------------------------------------------------------------------$task = mosGetParam($_REQUEST,'task','');$value = mosGetParam($_REQUEST, 'value', '');$region = mosGetParam($_REQUEST,'region','');$zone = mosGetParam($_REQUEST,'zone','');$city = mosGetParam($_REQUEST,'city','');$settlement = mosGetParam($_REQUEST,'settlement','');$street = mosGetParam($_REQUEST,'street','');$buildingId = mosGetParam($_REQUEST,'buildingId','');$streetId= mosGetParam($_REQUEST,'streetId','');$userIndex= mosGetParam($_REQUEST,'userIndex','');$value = ($value=="" ? 0 : str_replace("'", "''", $value));$zone = ($zone=="" ? 0 : str_replace("'", "''", $zone));$region = ($region=="" ? 0 : str_replace("'", "''", $region));$city = ($city=="" ? 0 : str_replace("'", "''", $city));$settlement = ($settlement=="" ? 0 : str_replace("'", "''", $settlement));$street = ($street=="" ? 0 : str_replace("'", "''", $street));$buildingId = ($buildingId=="" ? 0 : str_replace("'", "''", $buildingId));$streetId = ($streetId=="" ? 0 : str_replace("'", "''", $streetId));$userIndex = ($userIndex=="" ? 0 : str_replace("'", "''", $userIndex));$res = array();// Разобьем $value на собственно наименование и типmb_regex_encoding("utf-8");mb_ereg("^(.*)".        "\([[:space:]]*([[:alnum:]]*)",$value, $regs);if ($regs) {    $value = trim($regs[1]);    $type = $regs[2];}if ($type!="") $check_type = "AND types.name LIKE '$type%'";switch($task) {    case 'checkIndex':        if ($buildingId != 0) {            $query = "SELECT _index FROM buildings WHERE id = $buildingId LIMIT 1";            $database->setQuery($query);            $res = $database->loadResult();        } else if ($streetId != 0) {            $query = "SELECT _index FROM streets WHERE id = $streetId LIMIT 1";            $database->setQuery($query);            $res = $database->loadResult();        }        $_RESULT = array(            correct => ($res == $userIndex)        );        return;    case 'suggest':        if ($street != 0) {            // определяем дом, используя регулярные выражения MySql            // приведем дом к виду, как записываются дома в базе            $regs = array();            mb_ereg("^[[:space:]]*[д|Д]?(ом)?\.?[[:space:]]*([[:digit:]]+)".                    "([А-Я]?)(/([[:digit:]]+))?,?[[:space:]]*".                    "([к|К](орп)?\.?[[:space:]]*([[:digit:]]+))?,?[[:space:]]*".                    "([с|С](тр)?\.?[[:space:]]*([[:digit:]]+))?,?[[:space:]]*".                    "([в|В](лад)?\.?[[:space:]]*([[:digit:]]+))?[[:space:]]*",                    $value, $regs);            // 2 - номер дома            // 3 - буквенный корпус            // 5 - цифра после дроби            // 8 - цифровой корпус            // 11 - номер строения            // 14 - номер владения            $value = $regs[2];            if ($regs[3]!="") $value = $value.$regs[3];            if ($regs[8]!="") $value = $value."к".$regs[8];            if ($regs[11]!="") $value = $value."стр".$regs[11];            if ($regs[14]!="") $value = $value."влад".$regs[14];                                    $where_q = "WHERE parent_street = $street ";            $query = "SELECT temp.name, temp.korp, temp.id, _index, types.name AS type, 5 AS level FROM ".                     "    (SELECT name, korp, id, type, _index FROM buildings FORCE INDEX(parent_street) ".                     "$where_q) AS temp ".                     "        INNER JOIN types ON temp.type = types.id ";            $database->setQuery($query);            $res = $database->loadObjectList();                        $korp = ($regs[2] == "") ? $regs[6] : $regs[2];            $number = $regs[1];                        $regs = null;            $candidats = array();            // Добавим все записи, претендующие на указанный дом            foreach ($res as $row) {                $r = explode(",", $row->name);                foreach ($r as $p) {                    // номер дома в точности совпадает с записью (напр. "12к1стр2"):                    if (strcmp($value, $p)==0 && $row->korp=="") {                        array_push($candidats, array(                            "id"=>$row->id,                            "priority"=>0                        ));                    }                    // цифровая часть дома совпадает, а корпус совпадает по полю korp                    if (strcmp($number, $p)==0 && strcmp($korp,$row->korp)==0) {                        array_push($candidats, array(                            "id"=>$row->id,                            "priority"=>0                        ));                    }                                        //номер дома совпадает частично (не считая корпусов, строений и владений)                    if (strcmp($number, $p)==0 && $row->korp=="") {                        array_push($candidats, array(                            "id"=>$row->id,                            "priority"=>1                        ));                    }                    // номер дома входит в диапазон (напр. "1-18")                    mb_ereg("^[0-9]+-[0-9]+",$p,$regs);                    if ($regs[0]) {                        $interval = explode("-", $regs[0]);                        if ($value>=$interval[0] && $value<=$interval[1]) {                            array_push($candidats, array(                                "id"=>$row->id,                                "priority"=>3                            ));                        }                    }                     // номер дома входит в диапазон четных или нечетных номеров (напр. "Ч(2-24)")                    if ($value%2==0) {                        // только для четных номеров                        mb_ereg("^Ч\([0-9]+-[0-9]+\)",$p,$regs);                        if ($regs[0]) {                            $interval = mb_substr($regs[0],3,mb_strlen($regs[0])-4);                            $interval = explode("-", $interval);                            if ($value>=$interval[0] && $value<=$interval[1]) {                                array_push($candidats, array(                                    "id"=>$row->id,                                    "priority"=>4                                ));                            }                        }                     } else {                        // только для нечетных                        mb_ereg("^Н\([0-9]+-[0-9]+\)",$p,$regs);                        if ($regs[0]) {                            $interval = mb_substr($regs[0],3,mb_strlen($regs[0])-4);                            $interval = explode("-", $interval);                            if ($value>=$interval[0] && $value<=$interval[1]) {                                array_push($candidats, array(                                    "id"=>$row->id,                                    "priority"=>4                                ));                            }                        }                     }                                        $regs = null;                }            }                        // найдем самую приоритетную запись            $min = null;            foreach($candidats as $c) {                if ($min==null) {                    $min = $c;                } else {                    if ($min["priority"] > $c["priority"]) $min = $c;                }            }                                    $_RESULT = array(                "id" => $min["id"],                "level" => 5            );            return;        } else if ($settlement != 0 && $street == 0) {            // определяем улицу, дом также может принадлежать поселению            // TODO: добавить определение домов из предыдущей ветки            $where_q = "WHERE parent_settlement = $settlement AND name LIKE '$value%' ";            $query = "SELECT temp.name, temp.id, types.name AS type, 4 AS level FROM ".                     "    (SELECT name, id, type FROM streets FORCE INDEX(parent_settlement) ".                     "$where_q LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type ".                     "ORDER BY name LIMIT 10";            $database->setQuery($query);            $res = $database->loadObjectList();        } else if ($city != 0 && $settlement == 0 && $street == 0) {            // определяем поселение или улицу            $where_q1 = "WHERE parent_city = $city AND name LIKE '$value%'";            $where_q2 = "WHERE parent_city = $city AND name LIKE '$value%' AND parent_settlement IS NULL";            $query = "(SELECT temp.name, temp.id, types.name AS type, 3 AS level FROM ".                     "    (SELECT name, id, type FROM settlements $where_q1 LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type)".                     "UNION ".                     "(SELECT temp.name, temp.id, types.name AS type, 4 AS level FROM ".                     "    (SELECT name, id, type FROM streets FORCE INDEX(parent_city) ".                     "$where_q2 LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type)".                                          "ORDER BY name LIMIT 10";            $database->setQuery($query);            $res = $database->loadObjectList();        } else if ($zone !=0 && $city == 0 && $settlement == 0 && $street == 0) {            $where_q = "WHERE parent_zone = $zone AND name LIKE '$value%'";            $query = "(SELECT temp.name, temp.id, types.name AS type, 2 AS level FROM ".                     "    (SELECT name, id, type FROM cities $where_q LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type) ".                     "UNION ".                     "(SELECT temp.name, temp.id, types.name AS type, 3 AS level FROM ".                     "    (SELECT name, id, type FROM settlements $where_q LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type)".                     "ORDER BY name LIMIT 10";            $database->setQuery($query);            $res = $database->loadObjectList();        } else if ($region !=0 && $zone ==0 && $city ==0 && $settlement ==0 && $street ==0) {            $query = "SELECT short_name FROM types WHERE id=(SELECT type FROM regions WHERE id='$region')";            $database->setQuery($query);            $type = $database->loadRow();            if ($type[0] == "г") {            // если субъект-город: выводим города, поселения, улицы                $where_q1 = "WHERE parent_region = $region AND name LIKE '$value%' AND parent_zone IS NULL";                $where_q2 = "WHERE parent_region = $region AND name LIKE '$value%' AND parent_zone IS NULL AND parent_city IS NULL";                $where_q3 = "WHERE parent_region = $region AND name LIKE '$value%' AND parent_city IS NULL AND parent_settlement IS NULL";                $query = "(SELECT temp.name, temp.id, types.name AS type, 2 AS level FROM ".                         "    (SELECT name, id, type FROM cities $where_q1 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "UNION ".                         "(SELECT temp.name, temp.id, types.name AS type, 3 AS level FROM ".                         "    (SELECT name, id, type FROM settlements $where_q2 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "UNION ".                         "(SELECT temp.name, temp.id, types.name AS type, 4 AS level FROM ".                         "    (SELECT name, id, type FROM streets FORCE INDEX (parent_region) ".                         "$where_q3 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "ORDER BY name LIMIT 10";                $database->setQuery($query);                $res = $database->loadObjectList();            } else {                // определяем район                $where_q1 = "WHERE parent_region = $region AND name LIKE '$value%' ";                $where_q2 = "WHERE parent_region = $region AND name LIKE '$value%' AND parent_zone IS NULL";                $where_q3 = "WHERE parent_region = $region AND name LIKE '$value%' AND parent_zone IS NULL AND parent_city IS NULL";                $query = "(SELECT temp.name, temp.id, types.name AS type, 1 AS level FROM ".                         "    (SELECT name, id, type FROM zones $where_q1 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "UNION ".                         "(SELECT temp.name, temp.id, types.name AS type, 2 AS level FROM ".                         "    (SELECT name, id, type FROM cities $where_q2 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "UNION ".                         "(SELECT temp.name, temp.id, types.name AS type, 3 AS level FROM ".                         "    (SELECT name, id, type FROM settlements $where_q3 LIMIT 10) AS temp ".                         "        INNER JOIN types ON temp.type = types.id $check_type) ".                         "ORDER BY name LIMIT 10";                $database->setQuery($query);                $res = $database->loadObjectList();            }        } else if ($region ==0 && $zone ==0 && $city ==0 && $settlement == 0 && $street == 0) {            // определяем субъект            $where_q = "WHERE name LIKE '$value%'";            $query = "SELECT temp.name, temp.id, types.name AS type, 0 AS level FROM ".                     "    (SELECT name, id, type FROM regions $where_q LIMIT 10) AS temp ".                     "        INNER JOIN types ON temp.type = types.id $check_type ".                     "ORDER BY name LIMIT 10";            $database->setQuery($query);            $res = $database->loadObjectList();        }    // JsHTTPRequst неправильно отсылает объекты на сервере etersoft,    // поэтому переведем их в ассоциативный массив    $rr = array();    if (!empty($res)) {        foreach($res as $r) {            array_push($rr, array(            "name" => $r->name,            "type" => $r->type,            "id" => $r->id,            "level" => $r->level           ));        }    }    $_RESULT = $rr;    break;}?>
Note: See TracBrowser for help on using the browser.