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
+