$a = array_merge($a, $b); $a = array_unique($a); qpre(count($a), $a); exit; } if (isset($argv)) { $action = clb_val('', $argv, 1); switch ($action) { case 'names': //always index all three station/stop types $index = array(); $query = 'SELECT ' . RF_NODES_SELECT . ' FROM ' . RF_NODES_FROM . ' WHERE ' . RF_NODES_TYPE . ' IN ' . clb_join($metaphone_types, TRUE); $sel = $wpdb->get_results($query, ARRAY_A); if (is_array($sel)) { foreach ($sel as $row) { $name = pfind_unify_names($row[RF_NODES_NAME]); $words = preg_split('/\\W+/', $name, -1, PREG_SPLIT_NO_EMPTY); foreach ($words as $w) { if ($w == '&') { $w = 'and'; } $sound = metaphone($w); //sometimes the sound is nothing like a number or 'y' if ($sound) { $index[$sound][$row[RF_NODES_TYPE]][] = $row[RF_NODES_KEY]; } // alternative $index[$sound][$row['ptype']]['pnum'] = $name; } } $blob = clb_blob_enc($index, TRUE); //TRUE=binary
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; }
//(isset($argv)) { $mode = safe_val($argv, 1, 1); qlog(__LINE__, __FILE__, $mode); } else { $mode = safe_val($_REQUEST, 'm', 1); $path = ''; } switch ($mode) { case 'names': //copied code from find which should be here to build list of sound alike names //$index = pfind_sound_index($path, array('rail','tube','tram'), $table); $index = array(); $sel = do_query('SELECT pnum, title, ptype FROM ' . $table . ' WHERE ptype IN ' . clb_join($ptypes, TRUE), __FILE__, __LINE__, ''); if (is_array($sel)) { foreach ($sel as $row) { $name = pfind_unify_names($row['name']); $words = preg_split('/\\W+/', $name, -1, PREG_SPLIT_NO_EMPTY); foreach ($words as $w) { if ($w == '&') { $w = 'and'; } $sound = metaphone($w); //sometimes the sound is nothing like a number or 'y' if ($sound) { $index[$sound][$row['ptype']][] = $row['pnum']; } // alternative $index[$sound][$row['ptype']]['pnum'] = $name; } } if ($path && is_dir(dirname($path))) { $blob = clb_blob_enc($index, TRUE);