示例#1
0
function pfind_interpret($entries, $mode, &$waypoints, $path, $node_types)
{
    global $wpdb;
    $result = array();
    $result['error'] = 200;
    //start optimistically
    $result['error_str'] = 'no errors';
    $waypoints = array();
    if (clb_count($entries) <= 0) {
        $result['error'] = 400;
        $result['error_str'] = 'no locations received to parse';
        return $result;
    }
    //if only one entry we expect a a "to" separating origin and dest
    if (count($entries) == 1) {
        $entries = preg_split('/\\s+to\\s+/i', trim(reset($entries)), -1, PREG_SPLIT_NO_EMPTY);
    }
    if (clb_count($entries) == 1) {
        $result['error'] = 400;
        $result['error_str'] = 'only one location';
        return $result;
    }
    if (is_file($path)) {
        $path = dirname($path);
    }
    $path = clb_dir($path) . 'metaphones.txt';
    //like spelling city
    $index = FALSE;
    if (is_file($path)) {
        $data = file_get_contents($path);
        //, FILE_BINARY);
        $index = clb_blob_dec($data);
    }
    $pickone = array();
    foreach ($entries as $loc) {
        $loc = strtolower($loc);
        $sel = FALSE;
        $select = 'SELECT ' . RF_NODES_SELECT . ' FROM ' . RF_NODES_FROM . ' ';
        //'SELECT pnum, ptype, title, more, lat, lng FROM places ';
        $where = ' WHERE ';
        //the list of ptypes that will be used to limit the names search
        $ptypes = $node_types;
        //if more than one mode check if the user has added clarifying name to the name eg "oxford rail"
        if (count($ptypes) > 1) {
            foreach ($ptypes as $type) {
                if (clb_contains($loc, $type)) {
                    //allow the user to force a mode, by adding the code to the name
                    $ptypes = array($type);
                    //replace all other modes
                    $loc = trim(preg_replace('/\\s*\\b' . preg_quote($type) . '\\b\\s*/i', ' ', $loc));
                    //remove the signal from the name
                }
            }
        }
        //get rid of quotes and escapes
        $loc = trim(str_replace(array('\\', '"'), ' ', $loc));
        if (preg_match('/^\\s*(-?[\\.\\d]+)\\s*,\\s*(-?[\\.\\d]+)\\s*$/', $loc, $m)) {
            //waypoint given as lat/lng pair
            //limit search by node types
            if (clb_count($ptypes)) {
                $where .= ' ' . RF_NODES_TYPE . ' IN ' . clb_join($ptypes, TRUE) . ' AND ';
            }
            list($junk, $lat, $lng) = $m;
            for ($dist = 200; $dist <= 500; $dist += 100) {
                $sel = $wpdb->get_results($select . $where . within_rect($lat, $lng, $dist), ARRAY_A);
                $sel = clb_rekey($sel, RF_NODES_KEY);
                if (clb_count($sel) > 1) {
                    break;
                }
            }
            if (clb_count($sel) <= 0) {
                $result = array('error' => 602, 'error_str' => 'no tranpost node could be found near coordinates ' . $lat . ', ' . $lng);
                return $result;
            }
        } else {
            if (preg_match('/^node:\\s*(\\w+)\\s*$/', $loc, $m)) {
                //waypoint specified by pnum
                $sel = $wpdb->get_results($select . ' WHERE ' . RF_NODES_KEY . '=' . clb_escape($m[1]), ARRAY_A);
                $sel = clb_rekey($sel, RF_NODES_KEY);
            } else {
                if (in_array('rail', $ptypes) && preg_match('/^\\s*(\\w{3})\\s*$/', $loc, $m)) {
                    //rail station three letter code
                    $sel = $wpdb->get_results($select . ' WHERE ' . RF_NODES_TYPE . '="rail" AND (extref=' . clb_escape($m[1]) . ' OR ' . RF_NODES_NAME . '=' . clb_escape($m[1]) . ')', ARRAY_A);
                    $sel = clb_rekey($sel, RF_NODES_KEY);
                } else {
                    /*
                    	the primary key of the sound index structrue is the metaphone.  Inside that are ptypes using that saound.
                    	within each ptype there is a list of specific pnums using that sound in the name.
                    	on each first word, get all pnums for that sound and type, on subsequent words intesect with pnums
                    	so that we end up with pnums which have all sounds.
                    	$index[$sound][ptype][] => pnum
                    */
                    $sel = FALSE;
                    $name = pfind_unify_names($loc);
                    if (is_array($index)) {
                        $intersection = FALSE;
                        $words = preg_split('/\\W+/', $name, -1, PREG_SPLIT_NO_EMPTY);
                        foreach ($words as $w) {
                            if ($w == '&') {
                                $w = 'and';
                            }
                            $sound = metaphone($w);
                            if ($sound && isset($index[$sound])) {
                                $set = array();
                                foreach ($index[$sound] as $ptype => $nodes) {
                                    if (in_array($ptype, $ptypes)) {
                                        $set = array_merge($set, $nodes);
                                    }
                                }
                                $intersection = !is_array($intersection) ? $set : array_intersect($set, $intersection);
                            }
                        }
                        if (clb_count($intersection)) {
                            $query = $select . $where . ' ' . RF_NODES_KEY . ' IN ' . clb_join($intersection, TRUE);
                            $sel = $wpdb->get_results($query, ARRAY_A);
                            $sel = clb_rekey($sel, RF_NODES_KEY);
                        }
                    } else {
                        $query = $select . $where . ' ' . RF_NODES_NAME . ' LIKE ' . clb_escape($name . '%');
                        if (clb_count($ptypes)) {
                            $query .= ' AND ' . RF_NODES_TYPE . ' IN ' . clb_join($ptypes, TRUE);
                        }
                        $sel = $wpdb->get_results($query, ARRAY_A);
                        $sel = clb_rekey($sel, RF_NODES_KEY);
                    }
                    //if more than one match scan for common words and remove the matches if they did not contain them
                    if (clb_count($sel) > 1) {
                        foreach ($sel as $i => $row) {
                            //exact match go for it alone
                            if (strtolower($row[RF_NODES_NAME]) == strtolower($loc)) {
                                $sel = array($i => $row);
                                break;
                            }
                            //if the full name contains "road" but the requested name does not
                            //omit this choice to avoid stations like "london road" when looking for london
                            if (preg_match('/\\b(road)\\b/i', $row[RF_NODES_NAME], $m)) {
                                if (!clb_contains($loc, $m[1], FALSE)) {
                                    unset($sel[$i]);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (clb_count($sel) <= 0) {
            $result = array('error' => 602, 'error_str' => 'no stations with the name ' . $loc);
            return $result;
        }
        $waypoints[] = $sel;
    }
    return $result;
}
示例#2
0
            }
        }
        break;
    case 'metaphone':
        $name = 'cambridge';
        $name = unify_names($name);
        $name = metaphone($name);
        qpre($name);
        $name = metaphone('(wales)');
        qpre($name);
        $path = __FILE__;
        $folder = '/Users/tobylewis/Sites/buses_sched/temp/';
        //if local use a folde that can be written to
        $folder = is_dir($folder) ? $folder . 'file' : $path;
        //otherwise use same folder as the p2p files
        $path = clb_dir(dirname($folder)) . 'metaphone.txt';
        $data = file_get_contents($path, FILE_BINARY);
        //need different p2p files for different combinations of modes
        $index = clb_blob_dec($data);
        ksort($index);
        qpre($index);
}
if (IS_CLI) {
    db_close();
    exit;
} else {
    if ($path) {
        clb_timing(__LINE__);
        $data = file_get_contents($path, FILE_BINARY);
        clb_timing('load');
        $map = clb_blob_dec($data);