#!/usr/bin/env ruby
# coding: utf-8
# Create uMap-format GeoJSON correction from Loremap DB

# Usage: ./vdb2umap.rb MAPTYPE				: out .umap to stdout
#   or
#   	 VDB2UMAP=/tmp/outputdir ./vdb2umap MAPTYPE	: output all files

require 'sqlite3'
require 'json'
require 'csv'

# Test1: extract by maptype:
# Usage: ./vdb2umap.rb tourist
#	Create .umap file of "tourist" theme

ARGV[0]==nil and abort "Specify MAPTYPE.  eg) #{$0} tourist"
mtype = ARGV[0]
sq3 = ENV["DBFILE"] || "db/viewer_prc.sq3"
mapdb = SQLite3::Database.new(sq3)
mapdb.results_as_hash = true
vdboutdir = ENV["VDBOUTDIR"]
quiet = ENV["QUIET"]

# ename|name|addr|lat|lon|maptype|attr|value|objtype|jsonval

r = mapdb.execute(<<-EOF, mtype)
	SELECT ename, name, addr, lat, lon, value as Desc, objtype, jsonval
	FROM mapitem NATURAL JOIN object NATURAL JOIN attribute
	WHERE ename IN (SELECT ename FROM maptype WHERE maptype=?)
	  AND attr='description'
	EOF
if r.empty? then
  $stderr.puts "None."
  exit 0
end

umap = {
  'type'	=> 'umap-mimic',
  'properties'	=> {'description' => 'Generated from vdb2umap'},
  'geometry'	=> {
    "type" => "Point",
    "coordinates" => [139.82866287231448, 38.89744587262311]
  },
}
layers = {}
layerdelimRX = /^layer\[(.*?)\]=/m	# Layer Division Format
defaultlayer = mtype || "Default"
r.each do |ent|
  # ename, name, addr, lat, lon, Desc, objtype, jsonval
  d = ent['Desc']
  featurebase = {
    'type'	=> 'Feature',
    'properties'=>   {}
  }
  propbase = {
    'ename'		=> ent['ename'],		# unnecessary
    'name'		=> ent['name'],
    ## 'description'	=> d,
  }
  # Check additional layer description
  # printf("%s(desc) = %s\n", ent['name'], d)
  deschash = {'description' => d}
  if layerdelimRX =~ d
    while layerdelimRX =~ d			# Hmm, scan() cannot be used
      d, layer = $', $1
      #layers[layer] = d.sub(layerdelimRX, "")	# extract layer name and desc
      layers[layer] ||= {
        "type"		=> "FeatureCollection",
        "features"	=> []
      }
      feature = featurebase.merge({
	'properties' => propbase.merge({'description' => d.split(layerdelimRX)[0]}),
        'geometry' => {
          'type'	=> ent['objtype'],
          'coordinates'	=> JSON.parse(ent['jsonval'])
        }
      })
      layers[layer]["features"] << feature
    end
  else
    layers[defaultlayer] ||= {
      "type"		=> "FeatureCollection",
      "features"	=> []
    }
    feature = featurebase.merge({
      'properties' => propbase.merge({'description' => d}),
      'geometry' => {
	'type'		=> ent['objtype'],
	'coordinates'	=> JSON.parse(ent['jsonval'])
      }
    })
    layers[defaultlayer]["features"] << feature
  end
end

umaplayers = []
layers.each do |name, ly|
  umaplayers << ly.merge({"_umap_options" => {"name" => name}})
end
umap['layers'] = umaplayers
if vdboutdir then
  umaplayers.each do |ul|
    if ul["_umap_options"] && ul["_umap_options"]["name"] then
      fn = ul["_umap_options"]["name"].gsub(/[^-0-9a-z._+ 	]/i, "")
      next if fn == ""
      fn += ".geojson"
      test(?d, vdboutdir) || Dir.mkdir(vdboutdir)
      test(?d, vdboutdir) || test(?w, vdboutdir) ||
        abort("Cannout write to [%s]", vdboutdir)
      path = File.expand_path(fn, vdboutdir)
      open(path, "w") do |jso|
        jso.write(JSON.pretty_generate(ul))
        quiet or $stderr.printf("Output %s GeoJSON to %s\n", fn, path)
      end
    end
    path = File.expand_path(mtype+".umap", vdboutdir)
    open(path, "w") do |um|
      um.write(JSON.pretty_generate(umap))
      quiet or $stderr.printf("Output ALL to %s\n", path)
    end
  end
else
  print JSON.pretty_generate(umap)
end
