active_road 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.rspec +1 -0
- data/.travis.yml +7 -2
- data/Gemfile +8 -2
- data/Guardfile +2 -6
- data/README.md +69 -9
- data/Rakefile +8 -7
- data/active_road.gemspec +19 -15
- data/app/models/active_road/access_link.rb +4 -4
- data/app/models/active_road/access_point.rb +5 -9
- data/app/models/active_road/boundary.rb +41 -0
- data/app/models/active_road/junction.rb +4 -18
- data/app/models/active_road/junction_conditionnal_cost.rb +2 -0
- data/app/models/active_road/junctions_physical_road.rb +5 -0
- data/app/models/active_road/logical_road.rb +5 -4
- data/app/models/active_road/osm_pbf_importer.rb +293 -0
- data/app/models/active_road/osm_pbf_importer_level_db.rb +784 -0
- data/app/models/active_road/path.rb +40 -9
- data/app/models/active_road/physical_road.rb +22 -27
- data/app/models/active_road/physical_road_conditionnal_cost.rb +3 -1
- data/app/models/active_road/request_conditionnal_cost_linker.rb +59 -0
- data/app/models/active_road/street_number.rb +60 -57
- data/app/models/active_road/terra_importer.rb +161 -0
- data/db/migrate/20120419093427_add_kind_to_physical_roads.rb +2 -2
- data/db/migrate/20140206091734_create_boundaries.rb +16 -0
- data/db/migrate/20140210132933_add_attributes_to_physical_road.rb +9 -0
- data/db/migrate/20140219095521_add_boundary_id_to_logical_road.rb +5 -0
- data/db/migrate/20140228072448_add_boundary_id_to_physical_road.rb +5 -0
- data/db/migrate/20140304141150_add_marker_to_physical_road.rb +5 -0
- data/db/migrate/20140310083550_add_tags_to_street_number.rb +5 -0
- data/db/migrate/20140317153437_add_index_to_conditionnal_costs.rb +6 -0
- data/db/migrate/20140602160047_add_physical_road_index_to_junctions_physical_road.rb +5 -0
- data/lib/active_road.rb +8 -2
- data/lib/active_road/engine.rb +4 -1
- data/lib/active_road/shortest_path/finder.rb +37 -46
- data/lib/active_road/simulation_tool.rb +73 -0
- data/lib/active_road/version.rb +1 -1
- data/lib/tasks/activeroad_tasks.rake +88 -4
- data/script/benchmark_import_kyotocabinet.rb +148 -0
- data/script/benchmark_shortest_path.rb +22 -0
- data/script/count_tag_in_osm_data.rb +114 -0
- data/script/import-tiger-numbers +3 -3
- data/spec/dummy/db/schema.rb +2 -1
- data/spec/dummy/db/structure.sql +100 -11
- data/spec/factories/boundary.rb +8 -0
- data/spec/factories/junction.rb +1 -1
- data/spec/factories/physical_road.rb +1 -2
- data/spec/fixtures/test.osm +120 -0
- data/spec/fixtures/test.osm.bz2 +0 -0
- data/spec/fixtures/test.osm.pbf +0 -0
- data/spec/lib/active_road/shortest_path/finder_spec.rb +143 -90
- data/spec/lib/active_road/shortest_path/performance_finder_spec.rb +59 -0
- data/spec/models/active_road/access_point_spec.rb +9 -18
- data/spec/models/active_road/junction_conditionnal_cost_spec.rb +4 -4
- data/spec/models/active_road/junction_spec.rb +34 -11
- data/spec/models/active_road/logical_road_spec.rb +20 -19
- data/spec/models/active_road/osm_pbf_importer_level_db_spec.rb +410 -0
- data/spec/models/active_road/path_spec.rb +1 -1
- data/spec/models/active_road/physical_road_conditionnal_cost_spec.rb +4 -4
- data/spec/models/active_road/physical_road_spec.rb +14 -3
- data/spec/models/active_road/request_conditionnal_cost_linker_spec.rb +65 -0
- data/spec/models/active_road/shared_examples/osm_pbf_importer_spec.rb +148 -0
- data/spec/models/active_road/street_number_spec.rb +58 -58
- data/spec/models/active_road/terra_importer_spec.rb +140 -0
- data/spec/spec_helper.rb +14 -9
- data/spec/support/geometry_support.rb +36 -0
- data/spec/support/profile.rb +19 -0
- data/tmp/performance/.gitignore +0 -0
- data/travis/before_install.sh +5 -9
- data/travis/before_script.sh +7 -7
- metadata +118 -121
- data/app/models/active_road/physical_road_filter.rb +0 -41
- data/app/models/active_road/terra_import.rb +0 -148
- data/spec/models/active_road/physical_road_filter_spec.rb +0 -85
- data/spec/models/active_road/terra_import_spec.rb +0 -113
- data/spec/support/georuby_ext.rb +0 -15
@@ -2,8 +2,8 @@ class AddKindToPhysicalRoads < ActiveRecord::Migration
|
|
2
2
|
def change
|
3
3
|
add_column :physical_roads, :kind, :string
|
4
4
|
|
5
|
-
ActiveRoad::PhysicalRoad.reset_column_information
|
6
|
-
ActiveRoad::PhysicalRoad.update_all :kind => "road"
|
5
|
+
#ActiveRoad::PhysicalRoad.reset_column_information
|
6
|
+
#ActiveRoad::PhysicalRoad.update_all :kind => "road"
|
7
7
|
|
8
8
|
add_index :physical_roads, :kind
|
9
9
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateBoundaries < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def change
|
4
|
+
create_table :boundaries do |t|
|
5
|
+
t.string :objectid
|
6
|
+
t.string :name
|
7
|
+
t.integer :admin_level
|
8
|
+
t.string :postal_code
|
9
|
+
t.string :insee_code
|
10
|
+
t.multi_polygon :geometry, :srid => ActiveRoad.srid
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :boundaries, :geometry, :spatial => true
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class AddAttributesToPhysicalRoad < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
add_column :physical_roads, :car, :boolean
|
4
|
+
add_column :physical_roads, :bike, :boolean
|
5
|
+
add_column :physical_roads, :train, :boolean
|
6
|
+
add_column :physical_roads, :pedestrian, :boolean
|
7
|
+
add_column :physical_roads, :name, :string
|
8
|
+
end
|
9
|
+
end
|
data/lib/active_road.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
require "active_road/engine"
|
2
2
|
require 'erb'
|
3
|
+
require 'saxerator'
|
4
|
+
require "activerecord-postgres-hstore"
|
5
|
+
require "enumerize"
|
6
|
+
require "pbf_parser"
|
7
|
+
require "postgis_adapter"
|
8
|
+
require "georuby-ext"
|
9
|
+
require 'snappy'
|
10
|
+
require 'postgres-copy'
|
3
11
|
|
4
12
|
module ActiveRoad
|
5
13
|
|
@@ -15,5 +23,3 @@ end
|
|
15
23
|
|
16
24
|
require "active_road/shortest_path"
|
17
25
|
require "active_road/shortest_path/finder"
|
18
|
-
|
19
|
-
|
data/lib/active_road/engine.rb
CHANGED
@@ -3,7 +3,10 @@ module ActiveRoad
|
|
3
3
|
require "active_road/migration"
|
4
4
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
|
-
|
6
|
+
config.generators do |g|
|
7
|
+
g.test_framework :rspec
|
8
|
+
end
|
9
|
+
|
7
10
|
initializer "active_road.factories", :after => "factory_girl.set_factory_paths" do
|
8
11
|
FactoryGirl.definition_file_paths << File.expand_path('../../../spec/factories', __FILE__) if defined?(FactoryGirl)
|
9
12
|
end
|
@@ -17,24 +17,22 @@ require 'shortest_path/finder'
|
|
17
17
|
|
18
18
|
class ActiveRoad::ShortestPath::Finder < ShortestPath::Finder
|
19
19
|
|
20
|
-
attr_accessor :speed, :physical_road_filter, :follow_way_filter, :user_weights
|
20
|
+
attr_accessor :speed, :physical_road_filter, :follow_way_filter, :user_weights, :request_conditionnal_costs_linker, :constraints
|
21
21
|
|
22
|
-
def initialize(departure, arrival, speed = 4, constraints =
|
22
|
+
def initialize(departure, arrival, speed = 4, constraints = [], follow_way_filter = {})
|
23
23
|
super departure, arrival
|
24
24
|
@speed = speed * 1000 / 3600 # Convert speed in meter/second
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
@user_weights = user_weights # Not used
|
25
|
+
@constraints = constraints
|
26
|
+
@follow_way_filter = follow_way_filter
|
27
|
+
@steps = 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def request_conditionnal_costs_linker
|
31
|
+
@request_conditionnal_costs_linker ||= ActiveRoad::RequestConditionnalCostLinker.new(constraints)
|
34
32
|
end
|
35
33
|
|
36
34
|
def destination_accesses
|
37
|
-
@destination_accesses ||= ActiveRoad::AccessPoint.to(destination
|
35
|
+
@destination_accesses ||= ActiveRoad::AccessPoint.to(destination)
|
38
36
|
end
|
39
37
|
|
40
38
|
# Return a time in second from node to destination
|
@@ -63,23 +61,18 @@ class ActiveRoad::ShortestPath::Finder < ShortestPath::Finder
|
|
63
61
|
path_weights += path_weight(path.length_in_meter) if path.respond_to?(:length_in_meter)
|
64
62
|
|
65
63
|
# Add junction weight if it's a junction with a waiting constraint
|
66
|
-
if
|
64
|
+
if !(GeoRuby::SimpleFeatures::Point === path) && ActiveRoad::Junction === path.departure && path.departure.waiting_constraint
|
67
65
|
path_weights += path.departure.waiting_constraint
|
68
66
|
end
|
69
|
-
|
70
|
-
#
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
# path_weights += path_weight(path_length, percentage)
|
79
|
-
# end
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# end
|
67
|
+
|
68
|
+
# Add physical road weight if it's a physical road
|
69
|
+
physical_road = path.physical_road if ActiveRoad::Path === path
|
70
|
+
physical_road_conditionnal_costs = physical_road.physical_road_conditionnal_costs if physical_road
|
71
|
+
|
72
|
+
if physical_road && physical_road_conditionnal_costs
|
73
|
+
cc_percentage = request_conditionnal_costs_linker.conditionnal_costs_sum(physical_road_conditionnal_costs)
|
74
|
+
path_weights += path_weight(path.length_in_meter, cc_percentage) if path.respond_to?(:length_in_meter)
|
75
|
+
end
|
83
76
|
|
84
77
|
path_weights
|
85
78
|
end
|
@@ -89,15 +82,7 @@ class ActiveRoad::ShortestPath::Finder < ShortestPath::Finder
|
|
89
82
|
end
|
90
83
|
|
91
84
|
def geometry
|
92
|
-
@geometry ||= GeoRuby::SimpleFeatures::LineString.merge path.collect
|
93
|
-
end
|
94
|
-
|
95
|
-
# Use to profile code
|
96
|
-
def self.example
|
97
|
-
from = (ENV['FROM'] or "30.030238,-90.061541")
|
98
|
-
to = (ENV['TO'] or "29.991739,-90.06918")
|
99
|
-
|
100
|
-
ActiveRoad::ShortestPath::Finder.new GeoRuby::SimpleFeatures::Point.from_lat_lng(from), GeoRuby::SimpleFeatures::Point.from_lat_lng(to)
|
85
|
+
@geometry ||= GeoRuby::SimpleFeatures::LineString.merge path.collect{ |n| n.to_geometry }.select{ |g| GeoRuby::SimpleFeatures::LineString === g }
|
101
86
|
end
|
102
87
|
|
103
88
|
#-----------------------------------------
|
@@ -123,7 +108,7 @@ class ActiveRoad::ShortestPath::Finder < ShortestPath::Finder
|
|
123
108
|
context_downhill = context[:downhill] ? context[:downhill] : 0
|
124
109
|
context_height = context[:height] ? context[:height] : 0
|
125
110
|
|
126
|
-
if(
|
111
|
+
if( ActiveRoad::Path === node )
|
127
112
|
departure = node.departure
|
128
113
|
physical_road = node.physical_road
|
129
114
|
|
@@ -144,28 +129,34 @@ class ActiveRoad::ShortestPath::Finder < ShortestPath::Finder
|
|
144
129
|
request = request && context[:uphill] <= follow_way_filter[:uphill] if follow_way_filter[:uphill] && context[:uphill].present?
|
145
130
|
request = request && context[:downhill] <= follow_way_filter[:downhill] if follow_way_filter[:downhill] && context[:downhill].present?
|
146
131
|
request = request && context[:height] <= follow_way_filter[:height] if follow_way_filter[:height] && context[:height].present?
|
147
|
-
request = request && search_heuristic(node) + weight < time_heuristic(source) *
|
132
|
+
request = request && ( search_heuristic(node) + weight ) < ( time_heuristic(source) * 4 )
|
148
133
|
end
|
149
134
|
|
150
|
-
def ways(node, context={})
|
135
|
+
def ways(node, context={})
|
151
136
|
paths =
|
152
137
|
if GeoRuby::SimpleFeatures::Point === node
|
153
|
-
|
138
|
+
# Search access to physical roads for departure
|
139
|
+
ActiveRoad::AccessLink.from(node)
|
154
140
|
else
|
155
|
-
node.paths
|
141
|
+
node.paths
|
156
142
|
end
|
157
|
-
|
158
|
-
|
143
|
+
|
144
|
+
# Search for each node if they have physical roads in common with arrival
|
145
|
+
# If true finish the trip and link to arrival
|
146
|
+
unless GeoRuby::SimpleFeatures::Point === node
|
159
147
|
destination_accesses.select do |destination_access|
|
160
|
-
if node.access_to_road?(destination_access.physical_road)
|
148
|
+
if node.access_to_road?(destination_access.physical_road) && !(ActiveRoad::AccessPoint === node.arrival)
|
161
149
|
paths << ActiveRoad::Path.new(:departure => node.arrival, :arrival => destination_access, :physical_road => destination_access.physical_road)
|
162
150
|
end
|
163
151
|
end
|
164
152
|
end
|
165
|
-
|
153
|
+
|
166
154
|
array = paths.collect do |path|
|
167
155
|
[ path, path_weights(path)]
|
168
|
-
end
|
156
|
+
end
|
157
|
+
|
158
|
+
@steps += 1
|
159
|
+
|
169
160
|
Hash[array]
|
170
161
|
end
|
171
162
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class ActiveRoad::SimulationTool
|
2
|
+
def self.sql_insert_junction( x, y)
|
3
|
+
x = (( x * 100000 ).to_i)/100000.0
|
4
|
+
y = (( y * 100000 ).to_i)/100000.0
|
5
|
+
"INSERT INTO junctions (objectid, created_at, updated_at, geometry) values ( '#{x}-#{y}', '2014-03-14 14:32:23.362164', '2014-03-14 14:32:23.362164', ST_geometryFromText('POINT( #{x} #{y})', 4326) );"
|
6
|
+
end
|
7
|
+
def self.sql_insert_physical_road( x1, y1, x2, y2)
|
8
|
+
x2 = (( x2 * 100000 ).to_i)/100000.0
|
9
|
+
y2 = (( y2 * 100000 ).to_i)/100000.0
|
10
|
+
x1 = (( x1 * 100000 ).to_i)/100000.0
|
11
|
+
y1 = (( y1 * 100000 ).to_i)/100000.0
|
12
|
+
"INSERT INTO physical_roads (objectid, created_at, updated_at, geometry) values ( '#{x1}-#{y1}-#{x2}-#{y2}', '2014-03-14 14:32:23.362164', '2014-03-14 14:32:23.362164', ST_geometryFromText('LINESTRING( #{x1} #{y1}, #{x2} #{y2})', 4326) );"
|
13
|
+
end
|
14
|
+
def self.save_simulated_square( size )
|
15
|
+
ActiveRoad::PhysicalRoad.connection.execute square_sqls( size ).join("\n")
|
16
|
+
ActiveRoad::PhysicalRoad.connection.execute relation_sqls.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def self.square_sqls( size)
|
21
|
+
result = []
|
22
|
+
step = (1.0 / size)
|
23
|
+
index_x = 0
|
24
|
+
0.upto( size) do |i_x|
|
25
|
+
index_y = 0
|
26
|
+
0.upto( size) do |i_y|
|
27
|
+
result << sql_insert_junction( index_x, index_y)
|
28
|
+
|
29
|
+
if i_y < size
|
30
|
+
result << sql_insert_physical_road( index_x, index_y, index_x, index_y+step)
|
31
|
+
end
|
32
|
+
if i_x < size
|
33
|
+
result << sql_insert_physical_road( index_x, index_y, index_x+step, index_y)
|
34
|
+
end
|
35
|
+
index_y += step
|
36
|
+
end
|
37
|
+
index_x += step
|
38
|
+
end
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def self.j_by_objectid
|
44
|
+
hash = {}
|
45
|
+
ActiveRoad::Junction.all.each do |j|
|
46
|
+
hash[ j.objectid ] = j.id
|
47
|
+
end
|
48
|
+
hash
|
49
|
+
end
|
50
|
+
def self.pr_by_objectid
|
51
|
+
hash = {}
|
52
|
+
ActiveRoad::PhysicalRoad.all.each do |pr|
|
53
|
+
hash[ pr.objectid ] = pr.id
|
54
|
+
end
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
def self.relation_sqls
|
58
|
+
result = []
|
59
|
+
pr_h = pr_by_objectid
|
60
|
+
j_h = j_by_objectid
|
61
|
+
pr_h.keys.each do |pr_objectid|
|
62
|
+
parts = pr_objectid.split("-")
|
63
|
+
j_start_objectid = "#{parts[0]}-#{parts[1]}"
|
64
|
+
j_end_objectid = "#{parts[2]}-#{parts[3]}"
|
65
|
+
|
66
|
+
result << "INSERT INTO junctions_physical_roads ( physical_road_id, junction_id ) values ( #{pr_h[ pr_objectid ]}, #{j_h[ j_start_objectid ]} );"
|
67
|
+
result << "INSERT INTO junctions_physical_roads ( physical_road_id, junction_id ) values ( #{pr_h[ pr_objectid ]}, #{j_h[ j_end_objectid ]} );"
|
68
|
+
end
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
data/lib/active_road/version.rb
CHANGED
@@ -1,4 +1,88 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
namespace :active_road do
|
3
|
+
|
4
|
+
desc 'This rebuilds environment db'
|
5
|
+
task :reset => :environment do
|
6
|
+
Rake::Task["db:drop"].invoke
|
7
|
+
Rake::Task["db:create"].invoke
|
8
|
+
Rake::Task["db:migrate"].invoke
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :import do
|
12
|
+
|
13
|
+
# bundle exec rake "app:active_road:import:osm_pbf_data[/home/user/test.osm.pbf, true]"
|
14
|
+
desc "Import osm data from a pbf file"
|
15
|
+
task :osm_pbf_data, [:file, :split_ways] => [:environment] do |task, args|
|
16
|
+
begin
|
17
|
+
puts "Import data from osm pbf file #{args.file} and with split_ways #{args.split_ways} with LevelDB"
|
18
|
+
raise "You should provide a valid osm file" if args.file.blank?
|
19
|
+
split_ways = args.split_ways == "true" ? true : false
|
20
|
+
ActiveRoad::OsmPbfImporterLevelDb.new(args.file, split_ways).import
|
21
|
+
puts "Completed import successfully."
|
22
|
+
rescue => e
|
23
|
+
puts("Failed to import osm data : " + e.message)
|
24
|
+
puts e.backtrace.join("\n")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Import terra data from a terra file"
|
29
|
+
task :terra_data, [:file] => [:environment] do |task, args|
|
30
|
+
begin
|
31
|
+
puts "Import data from terra file #{args.file}"
|
32
|
+
raise "You should provide a valid osm file" if args.file.blank?
|
33
|
+
start = Time.now
|
34
|
+
ActiveRoad::TerraImporter.new(args.file).import
|
35
|
+
#puts "OSM import finished in #{(Time.now - start).strftime('%H:%M:%S')} seconds"
|
36
|
+
puts "Completed import successfully."
|
37
|
+
rescue => e
|
38
|
+
puts("Failed to import terra data : " + e.message)
|
39
|
+
puts e.backtrace.join("\n")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
task :itinerary, [:from, :to, :speed, :constraints] => [:environment] do |task, args|
|
46
|
+
puts "Search an itinerary"
|
47
|
+
raise "You should provide arguments" if args.from.blank? || args.to.blank? || args.speed.blank?
|
48
|
+
start = Time.now
|
49
|
+
begin
|
50
|
+
finder = ActiveRoad::ShortestPath::Finder.new(args.from, args.to, args.speed, args.constraints).tap do |finder|
|
51
|
+
finder.timeout = 30.seconds
|
52
|
+
end
|
53
|
+
puts "Itinerary in json : #{finder.to_json}"
|
54
|
+
rescue => e
|
55
|
+
puts("Failed to find an itinerary : " + e.message)
|
56
|
+
end
|
57
|
+
puts "Itinerary research finished in #{(Time.now - start)} seconds"
|
58
|
+
end
|
59
|
+
|
60
|
+
# nammespace :install do
|
61
|
+
# task :dependencies do
|
62
|
+
# end
|
63
|
+
|
64
|
+
# task :kyotocabinet, [:file] => [:environment] do |task, args|
|
65
|
+
# sudo apt-get install -qq libgeos-dev libproj-dev postgresql-9.1-postgis liblzo2-dev liblzma-dev zlib1g-dev build-essential
|
66
|
+
|
67
|
+
# # Se placer dans le dossier /tmp
|
68
|
+
# cd /tmp
|
69
|
+
|
70
|
+
# # Installer kyotocabinet
|
71
|
+
# wget http://fallabs.com/kyotocabinet/pkg/kyotocabinet-1.2.76.tar.gz
|
72
|
+
# tar xzf kyotocabinet-1.2.76.tar.gz
|
73
|
+
# cd kyotocabinet-1.2.76
|
74
|
+
# ./configure –enable-zlib –enable-lzo –enable-lzma --prefix=/usr && make
|
75
|
+
# sudo make install
|
76
|
+
|
77
|
+
# # Installer les bindings ruby pour kyotocabinet
|
78
|
+
# cd /tmp
|
79
|
+
# wget http://fallabs.com/kyotocabinet/rubypkg/kyotocabinet-ruby-1.32.tar.gz
|
80
|
+
# tar xzf kyotocabinet-ruby-1.32.tar.gz
|
81
|
+
# cd kyotocabinet-ruby-1.32
|
82
|
+
# ruby extconf.rb
|
83
|
+
# make
|
84
|
+
# sudo make install
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'kyotocabinet'
|
2
|
+
include KyotoCabinet
|
3
|
+
|
4
|
+
class Node
|
5
|
+
attr_accessor :id, :lon, :lat, :ways, :end_of_way
|
6
|
+
|
7
|
+
def initialize(id, lon, lat, ways = [], end_of_way = false)
|
8
|
+
@id = id
|
9
|
+
@lon = lon
|
10
|
+
@lat = lat
|
11
|
+
@ways = ways
|
12
|
+
@end_of_way = end_of_way
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_way(id)
|
16
|
+
@ways << id
|
17
|
+
end
|
18
|
+
|
19
|
+
def marshal_dump
|
20
|
+
[@id, @lon, @lat, @ways, @end_of_way]
|
21
|
+
end
|
22
|
+
|
23
|
+
def marshal_load array
|
24
|
+
@id, @lon, @lat, @ways, @end_of_way = array
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class KCImport
|
29
|
+
|
30
|
+
def initialize(rnum, database_path = "/tmp/test.kch", options = "")
|
31
|
+
@rnum = rnum
|
32
|
+
@database_path = database_path
|
33
|
+
@options = options
|
34
|
+
end
|
35
|
+
|
36
|
+
# def database
|
37
|
+
# @database = DB::new
|
38
|
+
# end
|
39
|
+
|
40
|
+
def memoryusage()
|
41
|
+
rss = -1
|
42
|
+
file = open('/proc/self/status')
|
43
|
+
file.each do |line|
|
44
|
+
if line =~ /^VmRSS:/
|
45
|
+
line.gsub!(/.*:\s*(\d+).*/, '\1')
|
46
|
+
rss = line.to_i / 1024.0
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return rss
|
51
|
+
end
|
52
|
+
|
53
|
+
def import
|
54
|
+
DB::process(@database_path + @options, DB::OWRITER | DB::OCREATE | DB::OTRUNCATE) { |database|
|
55
|
+
|
56
|
+
#GC.start
|
57
|
+
musage = memoryusage
|
58
|
+
stime = Time.now
|
59
|
+
|
60
|
+
(0...@rnum).each do |i|
|
61
|
+
i_s = i.to_s
|
62
|
+
key = i_s
|
63
|
+
value = Marshal.dump(Node.new(i_s, rand, rand))
|
64
|
+
database[key] = value
|
65
|
+
end
|
66
|
+
|
67
|
+
etime = Time.now
|
68
|
+
#GC.start
|
69
|
+
|
70
|
+
printf("Count: %d\n", database.count)
|
71
|
+
printf("Time: %.3f sec.\n", etime - stime)
|
72
|
+
printf("Usage: %.3f MB\n", memoryusage - musage)
|
73
|
+
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def import_and_update
|
78
|
+
DB::process(@database_path + @options, DB::OWRITER | DB::OCREATE | DB::OTRUNCATE) { |database|
|
79
|
+
|
80
|
+
#GC.start
|
81
|
+
musage = memoryusage
|
82
|
+
stime = Time.now
|
83
|
+
|
84
|
+
(0...@rnum).each do |i|
|
85
|
+
i_s = i.to_s
|
86
|
+
key = i_s
|
87
|
+
value = Marshal.dump(Node.new(i_s, rand, rand))
|
88
|
+
database[key] = value
|
89
|
+
end
|
90
|
+
|
91
|
+
database.transaction {
|
92
|
+
(0...4000000).each do |way|
|
93
|
+
update_node_with_way(way, database)
|
94
|
+
end
|
95
|
+
}
|
96
|
+
|
97
|
+
etime = Time.now
|
98
|
+
#GC.start
|
99
|
+
|
100
|
+
printf("Count: %d\n", database.count)
|
101
|
+
printf("Time: %.3f sec.\n", etime - stime)
|
102
|
+
printf("Usage: %.3f MB\n", memoryusage - musage)
|
103
|
+
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def update_node_with_way(way, database)
|
108
|
+
way_id = way.to_s
|
109
|
+
nodes = [rand(6000000), rand(6000000), rand(6000000), rand(6000000), rand(6000000), rand(6000000), rand(6000000)]
|
110
|
+
|
111
|
+
# Take only the first and the last node => the end of physical roads
|
112
|
+
node_ids = nodes.collect(&:to_s)
|
113
|
+
|
114
|
+
# Update node data with way id
|
115
|
+
database.accept_bulk(node_ids) { |key, value|
|
116
|
+
node = Marshal.load(value)
|
117
|
+
node.add_way(way_id)
|
118
|
+
node.end_of_way = true if [nodes.first.to_s, nodes.last.to_s].include?(node.id)
|
119
|
+
Marshal.dump(node)
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
rnum = 6000000
|
126
|
+
if ARGV.length > 0
|
127
|
+
rnum = ARGV[0].to_i
|
128
|
+
end
|
129
|
+
|
130
|
+
# if ARGV.length > 1
|
131
|
+
# database_path = ARGV[1]
|
132
|
+
# end
|
133
|
+
|
134
|
+
# import in KC without options
|
135
|
+
puts "Import without options"
|
136
|
+
KCImport.new(rnum, "/home/luc/import_without_options.kch").import
|
137
|
+
|
138
|
+
# import in KC with options apow=8, opts=l, bnum=2000000 and msiz=50000000
|
139
|
+
puts "\nImport with options apow=8, opts=l, bnum=2000000 and msiz=50000000"
|
140
|
+
KCImport.new(rnum, "/home/luc/import_with_options.kch", "#apow=8#opts=l#bnum=2000000#msiz=50000000").import
|
141
|
+
|
142
|
+
# import in KC without options
|
143
|
+
puts "\nImport and update without options"
|
144
|
+
KCImport.new(rnum, "/home/luc/import_without_options.kch").import_and_update
|
145
|
+
|
146
|
+
# import in KC with options apow=8, opts=l, bnum=2000000 and msiz=50000000
|
147
|
+
# puts "\nImport and update with options apow=8, opts=l, bnum=2000000 and msiz=50000000"
|
148
|
+
# KCImport.new(rnum, "/home/luc/import_with_options.kch", "#apow=8#opts=l#bnum=2000000#msiz=50000000").import_and_update
|