function match_simplify($match, $method=0) { switch($match[0]) { case "or": for($i=1; $i<sizeof($match); $i++) { // or aufloesen $match[$i]=match_simplify($match[$i], $method); if($match[$i][0]=="or") { array_shift($match[$i]); $match=array_merge($match, $match[$i]); unset($match[$i]); $match=array_values($match); $i--; } } for($i=1; $i<sizeof($match); $i++) { for($j=1; $j<$i; $j++) { if(($match[$i][0]=="is")&&($match[$j][0]=="is")&& ($match[$i][1]==$match[$j][1])) { unset($match[$j][0]); unset($match[$j][1]); $match[$i]=array_merge($match[$i], $match[$j]); unset($match[$j]); $match=array_values($match); $j--; $i--; } elseif(($match[$i][0]=="~is")&&($match[$j][0]=="~is")&& ($match[$i][1]==$match[$j][1])) { unset($match[$j][0]); unset($match[$j][1]); $match[$i]=array_merge($match[$i], $match[$j]); unset($match[$j]); $match=array_values($match); $j--; $i--; } elseif(($match[$i][0]=="and")&&($match[$j][0]=="and")) { $eq=array(); $not_eq=array(); for($ii=1; $ii<sizeof($match[$i]); $ii++) { $found_eq=false; for($ji=1; $ji<sizeof($match[$j]); $ji++) { if(!sizeof(array_diff($match[$i][$ii], $match[$j][$ji]))) { $found_eq=true; $eq[]=$match[$i][$ii]; unset($match[$j][$ji]); $match[$j]=array_values($match[$j]); } elseif(((($match[$i][$ii][0]==">")&&($match[$j][$ji][0]=="<="))|| (($match[$i][$ii][0]==">=")&&($match[$j][$ji][0]=="<"))|| (($match[$i][$ii][0]==">=")&&($match[$j][$ji][0]=="<=")))&& ($match[$i][$ii][1]==$match[$j][$ji][1])&& ($match[$i][$ii][2]<=$match[$j][$ji][2])) { $found_eq=true; unset($match[$j][$ji]); $match[$j]=array_values($match[$j]); } elseif((($match[$i][$ii][0]=="exist")&& (in_array($match[$j][$ji][0], array(">", ">=", "<=", "<", "is"))))&& ($match[$i][$ii][1]<=$match[$j][$ji][1])) { $found_eq=true; $eq[]=$match[$i][$ii]; unset($match[$j][$ji]); $match[$j]=array_values($match[$j]); } } if(!$found_eq) { $not_eq[]=$match[$i][$ii]; } } if(sizeof($eq)) { if((!sizeof($not_eq))||(!sizeof($match[$j]))) { $match[$i]=$eq; unset($match[$j]); $match=array_values($match); $i--; } else { $not_eq=array(array_merge(array("or"), $not_eq, array($match[$j]))); $match[$i]=array_merge(array("and"), $eq, $not_eq); $il=sizeof($match[$i])-1; $match[$i][$il]=match_simplify($match[$i][$il], $method); unset($match[$j]); $match=array_values($match); $i--; } } } } } if(($match[0]=="or")&&(sizeof($match)==2)) { $match=$match[1]; } break; case "and": for($i=1; $i<sizeof($match); $i++) { // or aufloesen $match[$i]=match_simplify($match[$i], $method); if($match[$i][0]=="and") { array_shift($match[$i]); $match=array_merge($match, $match[$i]); unset($match[$i]); $match=array_values($match); $i--; } } if(($match[0]=="and")&&(sizeof($match)==2)) { $match=$match[1]; } break; } return $match; }
function build_sql_match_table($rules, $table="point", $id="tmp", $importance) { $tag_list=array(); $add_columns=array(); if(!sizeof($rules)) return null; $match_list=$rules['match']; $select=array(); $where=array(); $select[]="osm_id"; $select[]="osm_way as geo"; $select[]="osm_way_point as geo_point"; $select[]="osm_way_line as geo_line"; $select[]="osm_way_polygon as geo_polygon"; $select[]="osm_tags"; $or_list=array("or"); $i=0; foreach($match_list as $i=>$match) { $or_list[]=$match; } $w=match_to_sql(match_simplify($or_list), array("table"=>$table, "id"=>$id), "index"); $where[]="($w)"; $from="from osm_all_$table\n"; $funname="classify_{$id}_{$table}"; $select[]="$funname(osm_id, osm_tags, osm_way) as result"; //$where[]="(\"rule_$id\"='$importance' or \"rule_$id\" is null)"; // if(in_array($importance, array("global", "international", "national"))) // $where[]="Intersects(osm_way, !bbox!)"; // else $where[]="osm_way&&!bbox!"; print "WHERE"; print_r($where); if(sizeof($where)) $where="where\n ".implode(" and\n ", $where); else $where=""; $select=implode(", ", $select); return "select t2.osm_id as osm_id, t2.geo, t2.geo_point, t2.geo_line, t2.geo_polygon, t2.osm_tags as osm_tags, t2.result->'rule_id' as rule_id, t2.result->'importance' as importance, result as rule_tags from (select {$select} {$from} {$where}) as t2 where t2.result->'importance'='$importance'";// group by t2.result[1], t2.result[2], t2.result[3]"; //return "select array_to_string(to_textarray(t2.osm_id), ';') as osm_id, ST_Collect(t2.geo) as geo, tags_merge(to_array(t2.osm_tags)) as osm_tags, t2.result[1] as rule_id, t2.result[2] as importance, tags_merge(to_array(cd.rule_tags)) as rule_tags from (select {$select} {$from} {$where}) as t2 join categories_def cd on cd.category_id='$id' and cd.rule_id=t2.result[1] and t2.result[2]='$importance' group by t2.result[1], t2.result[2], t2.result[3]"; //select *, rule_tags->'display_name_pattern' as display_name_pattern, rule_tags->'display_type_pattern' as display_type_pattern, rule_tags->'icon_text_pattern' as icon_text_pattern from ( }