null+****@clear*****
null+****@clear*****
2012年 5月 11日 (金) 19:58:11 JST
HAYASHI Kentaro 2012-05-11 19:58:11 +0900 (Fri, 11 May 2012) New Revision: 10244bea6275b3cea99aa46508ac11649fa9fee4 Log: test: add grntest generator script for geo_distance Added files: test/function/tools/geo/generate-grntest-data.rb Added: test/function/tools/geo/generate-grntest-data.rb (+310 -0) 100755 =================================================================== --- /dev/null +++ test/function/tools/geo/generate-grntest-data.rb 2012-05-11 19:58:11 +0900 (377f39c) @@ -0,0 +1,310 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +require 'fileutils' +require 'optparse' + +TABLE_CREATE = "table_create Geo TABLE_HASH_KEY ShortText\n" +COLUMN_CREATE = "column_create Geo distance COLUMN_SCALAR Int32\n" +LOAD = <<-EOF +load --table Geo +[ +{"_key": "the record for geo_distance() result"} +] +EOF +CREATE_RESULT = "[[0,0.0,0.0],true]\n" +LOAD_RESULT = "[[0,0.0,0.0],1]\n" + +SELECT_PRE = "[[0,0.0,0.0],[[[1],[[\"_score\",\"Int32\"]],[" +SELECT_POST = "]]]]" + +def is_long(start_lng_deg, end_lng_deg) + if start_lng_deg != end_lng_deg and + ((start_lng_deg > 0 && end_lng_deg.to_i < 0) or + (start_lng_deg < 0 && end_lng_deg.to_i > 0)) and + start_lng_deg.abs + end_lng_deg.to_i.abs > 180 then + # the difference in longitude striding accross meridian is over + # 180 degree. + return true + else + return false + end +end + +def get_quadrant(lng, lat) + if (lng > 0 && lat > 0) then + return "1st" + elsif (lng < 0 && lat > 0) then + return "2nd" + elsif (lng < 0 && lat < 0) then + return "3rd" + elsif (lng > 0 && lat < 0) then + return "4th" + else + return nil + end +end + +def is_meridian(lng, lat) +end + +def is_equator(lng, lat) +end + +def is_east_axis(lng, lat) + if lng >= 0 and lat == 0 then + return true + else + return false + end +end + +def is_west_axis(lng, lat) + if lng <= 0 and lat == 0 then + return true + else + return false + end +end + +def is_north_axis(lng, lat) + if lng == 0 and lat >= 0 then + return true + else + return false + end +end + +def is_south_axis(lng, lat) + if lng == 0 and lat <= 0 then + return true + else + return false + end +end + +def is_point(start_lng, start_lat, end_lng, end_lat) + if start_lng == end_lng && start_lat == end_lat then + return true + else + return false + end +end + +def get_quadrant_to(start_lng, start_lat, end_lng, end_lat) + ret = "" + squadrant = get_quadrant(start_lng, start_lat) + equadrant = get_quadrant(end_lng, end_lat) + # p squadrant + # p equadrant + # p start_lng + # p start_lat + # p end_lng + # p end_lat + if (start_lng == end_lng && start_lng == 0) then + ret = "meridian" + elsif (start_lat == end_lat && start_lat == 0) then + ret = "equator" + elsif !squadrant or !equadrant then + if (not squadrant) && (not equadrant) then + if is_east_axis(start_lng, start_lat) && is_north_axis(end_lng, end_lat) || + is_north_axis(start_lng, start_lat) && is_east_axis(end_lng, end_lat) then + return "1st" + elsif is_north_axis(start_lng, start_lat) && is_west_axis(end_lng, end_lat) || + is_west_axis(start_lng, start_lat) && is_north_axis(end_lng, end_lat) then + return "2nd" + elsif is_west_axis(start_lng, start_lat) && is_south_axis(end_lng, end_lat) || + is_south_axis(start_lng, start_lat) && is_west_axis(end_lng, end_lat) then + return "3rd" + elsif is_east_axis(start_lng, start_lat) && is_south_axis(end_lng, end_lat) || + is_south_axis(start_lng, start_lat) && is_east_axis(end_lng, end_lat) then + return "4th" + end + elsif not squadrant then + ret = equadrant + elsif not equadrant then + ret = squadrant + end + else + if squadrant == equadrant then + ret = equadrant + else + ret = "#{squadrant}to#{equadrant}" + end + end + ret +end + +def get_point(lng, lat) + ret = "" + # lng -> lat + lng_desc = { + 0 => { + 90 => "north_pole_on_meridian", + 89 => "near_north_pole_on_meridian", + 1 => "near_positive_origin_on_meridian", + 0 => "origin_on_meridian", + -1 => "near_negative_origin_on_meridian", + -89 => "near_south_pole_on_meridian", + -90 => "south_pole_on_meridian", + }, + -180 => "west_edge", + -179 => "near_west_edge", + -91 => "west_near_ninety_degrees", + -90 => "west_ninety_degrees", + -89 => "west_near_ninety_degrees", + -1 => "near_negative_origin", + 1 => "near_positive_origin", + 89 => "east_near_ninety_degrees", + 90 => "east_ninety_degrees", + 91 => "east_near_ninety_degrees", + 179 => "near_east_edge", + } + lat_desc = { + 0 => { + -180 => "west_edge_on_equator", + -179 => "near_west_edge_on_equator", + -91 => "west_near_ninety_degrees_on_equator", + -90 => "west_ninety_degrees_on_equator", + -89 => "west_near_ninety_degrees_on_equator", + -1 => "near_nagative_origin_on_equator", + 0 => "origin", + 1 => "near_positive_origin_on_equator", + 89 => "east_near_ninetydegrees_on_equator", + 90 => "east_ninety_degrees_on_equator", + 91 => "east_near_ninety_degrees_on_equator", + 179 => "near_east_edge_on_equator", + }, + 90 => "north_pole", + 89 => "near_north_pole", + 1 => "near_positive_origin", + -1 => "near_negative_origin", + -89 => "near_south_pole", + -90 => "south_pole", + } + if lng == 0 then + return lng_desc[lng][lat] + elsif lat == 0 then + return lat_desc[lat][lng] + else + return lng_desc[lng] + "_" + lat_desc[lat] + end +end + +def get_filename(start_lng, start_lat, end_lng, end_lat) + s = get_point(start_lng, start_lat) + e = get_point(end_lng, end_lat) + if s == e then + ret = "#{s}.test" + else + ret = "#{s}_to_#{e}.test" + end + ret +end + +def parse_line_data(data) + lng_sdeg, lat_sdeg, lng_edeg, lat_edeg, + lng_start, lat_start, lng_end, lat_end, + distance, filename = data.chomp.split(",") + + return [lng_sdeg.to_i, lat_sdeg.to_i, lng_edeg.to_i, lat_edeg.to_i, + lng_start, lat_start, lng_end, lat_end, distance, filename] +end + + +if __FILE__ == $0 then + + OPTS = {} + opt = OptionParser.new + opt.on('-g', '--generate-filename'){ |v| OPTS[:name] = v } + opt.on('-t', '--generate-test'){ |v| OPTS[:test] = v } + opt.on('-e', '--generate-expected'){ |v| OPTS[:expected] = v } + opt.on('-c [VAL]', '--csv [VAL]'){ |v| OPTS[:csv] = v } + opt.on('-v', '--verbose'){ |v| OPTS[:verbose] = v } + + opt.parse!(ARGV) + + exit if not OPTS.has_key? :csv + + File.open(OPTS[:csv], "r") {|fh| + lines = fh.readlines + + SELECT = "select Geo --output_columns distance " + + lines.each_with_index { |line,i| + next if i == 0 # skip header + + #puts "line No #{i}" + + lng_sdeg, lat_sdeg, lng_edeg, lat_edeg, + lng_start, lat_start, lng_end, lat_end, + distance, filename = parse_line_data(line) + + app_types = ["", "rectangle", "rect"] + app_types = [""] + + quadrant = get_quadrant_to(lng_sdeg, lat_sdeg, lng_edeg, lat_edeg) + + prefix = is_long(lng_sdeg, lng_edeg) ? "long" : "short" + + type = is_point(lng_sdeg, lat_sdeg, lng_edeg, lat_edeg) ? "point" : "line" + + if OPTS.has_key? :name then + filename = get_filename(lng_sdeg, lat_sdeg, lng_edeg, lat_edeg) + + puts "#{line.chomp}" + # show new generated filename + puts line.chomp.split(",")[0..-2].join(",") + ",#{prefix}/#{quadrant}/#{type}/#{filename}" + + elsif OPTS.has_key? :test then + app_types.each { |app_type| + scorer = "" + file_prefix = "" + select_postfix = "" + comment = sprintf("# from (longitude %s latitude %s) to (longitude %s latitude %s)\n", + lng_sdeg, lat_sdeg, lng_edeg, lat_edeg) + scorer = sprintf("--scorer 'distance = geo_distance(\"%sx%s\", \"%sx%s\"", + lng_start, lat_start, lat_end, lng_end, app_type) + if app_type == "" then + # default + select_postfix = ")'\n" + else + file_prefix = app_type + "_" + select_postfix = ", \"#{app_type}\")'\n" + end + dottest = sprintf("%s%s\n%s\n%s%s%s%s", + TABLE_CREATE, + COLUMN_CREATE, + LOAD, + comment, + SELECT, scorer, select_postfix) + + if filename and filename != "" then + testname = sprintf("%s/%s/%s/%s%s", + prefix, quadrant, type, + file_prefix, File.basename(filename)) + else + exit 1 + end + + if testname and not Dir.exists?(File.dirname(testname)) then + FileUtils.mkdir_p(File.dirname(testname)) + end + + if File.exists?(testname) then + # duplicated? + puts "Warning! #{testname} duplicated" + end + File.open(testname, "w+") { |f| + if OPTS.has_key? :verbose then + puts testname + puts dottest + end + f.puts dottest + } + } + end + } + } +end +