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.
Files changed (76) hide show
  1. checksums.yaml +15 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +7 -2
  4. data/Gemfile +8 -2
  5. data/Guardfile +2 -6
  6. data/README.md +69 -9
  7. data/Rakefile +8 -7
  8. data/active_road.gemspec +19 -15
  9. data/app/models/active_road/access_link.rb +4 -4
  10. data/app/models/active_road/access_point.rb +5 -9
  11. data/app/models/active_road/boundary.rb +41 -0
  12. data/app/models/active_road/junction.rb +4 -18
  13. data/app/models/active_road/junction_conditionnal_cost.rb +2 -0
  14. data/app/models/active_road/junctions_physical_road.rb +5 -0
  15. data/app/models/active_road/logical_road.rb +5 -4
  16. data/app/models/active_road/osm_pbf_importer.rb +293 -0
  17. data/app/models/active_road/osm_pbf_importer_level_db.rb +784 -0
  18. data/app/models/active_road/path.rb +40 -9
  19. data/app/models/active_road/physical_road.rb +22 -27
  20. data/app/models/active_road/physical_road_conditionnal_cost.rb +3 -1
  21. data/app/models/active_road/request_conditionnal_cost_linker.rb +59 -0
  22. data/app/models/active_road/street_number.rb +60 -57
  23. data/app/models/active_road/terra_importer.rb +161 -0
  24. data/db/migrate/20120419093427_add_kind_to_physical_roads.rb +2 -2
  25. data/db/migrate/20140206091734_create_boundaries.rb +16 -0
  26. data/db/migrate/20140210132933_add_attributes_to_physical_road.rb +9 -0
  27. data/db/migrate/20140219095521_add_boundary_id_to_logical_road.rb +5 -0
  28. data/db/migrate/20140228072448_add_boundary_id_to_physical_road.rb +5 -0
  29. data/db/migrate/20140304141150_add_marker_to_physical_road.rb +5 -0
  30. data/db/migrate/20140310083550_add_tags_to_street_number.rb +5 -0
  31. data/db/migrate/20140317153437_add_index_to_conditionnal_costs.rb +6 -0
  32. data/db/migrate/20140602160047_add_physical_road_index_to_junctions_physical_road.rb +5 -0
  33. data/lib/active_road.rb +8 -2
  34. data/lib/active_road/engine.rb +4 -1
  35. data/lib/active_road/shortest_path/finder.rb +37 -46
  36. data/lib/active_road/simulation_tool.rb +73 -0
  37. data/lib/active_road/version.rb +1 -1
  38. data/lib/tasks/activeroad_tasks.rake +88 -4
  39. data/script/benchmark_import_kyotocabinet.rb +148 -0
  40. data/script/benchmark_shortest_path.rb +22 -0
  41. data/script/count_tag_in_osm_data.rb +114 -0
  42. data/script/import-tiger-numbers +3 -3
  43. data/spec/dummy/db/schema.rb +2 -1
  44. data/spec/dummy/db/structure.sql +100 -11
  45. data/spec/factories/boundary.rb +8 -0
  46. data/spec/factories/junction.rb +1 -1
  47. data/spec/factories/physical_road.rb +1 -2
  48. data/spec/fixtures/test.osm +120 -0
  49. data/spec/fixtures/test.osm.bz2 +0 -0
  50. data/spec/fixtures/test.osm.pbf +0 -0
  51. data/spec/lib/active_road/shortest_path/finder_spec.rb +143 -90
  52. data/spec/lib/active_road/shortest_path/performance_finder_spec.rb +59 -0
  53. data/spec/models/active_road/access_point_spec.rb +9 -18
  54. data/spec/models/active_road/junction_conditionnal_cost_spec.rb +4 -4
  55. data/spec/models/active_road/junction_spec.rb +34 -11
  56. data/spec/models/active_road/logical_road_spec.rb +20 -19
  57. data/spec/models/active_road/osm_pbf_importer_level_db_spec.rb +410 -0
  58. data/spec/models/active_road/path_spec.rb +1 -1
  59. data/spec/models/active_road/physical_road_conditionnal_cost_spec.rb +4 -4
  60. data/spec/models/active_road/physical_road_spec.rb +14 -3
  61. data/spec/models/active_road/request_conditionnal_cost_linker_spec.rb +65 -0
  62. data/spec/models/active_road/shared_examples/osm_pbf_importer_spec.rb +148 -0
  63. data/spec/models/active_road/street_number_spec.rb +58 -58
  64. data/spec/models/active_road/terra_importer_spec.rb +140 -0
  65. data/spec/spec_helper.rb +14 -9
  66. data/spec/support/geometry_support.rb +36 -0
  67. data/spec/support/profile.rb +19 -0
  68. data/tmp/performance/.gitignore +0 -0
  69. data/travis/before_install.sh +5 -9
  70. data/travis/before_script.sh +7 -7
  71. metadata +118 -121
  72. data/app/models/active_road/physical_road_filter.rb +0 -41
  73. data/app/models/active_road/terra_import.rb +0 -148
  74. data/spec/models/active_road/physical_road_filter_spec.rb +0 -85
  75. data/spec/models/active_road/terra_import_spec.rb +0 -113
  76. data/spec/support/georuby_ext.rb +0 -15
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YWZlZDYwNDEyOGU0Yjk4OGU5NDU1ZmMxYjA4ZmIzNjk4ODAwZjMxOA==
5
+ data.tar.gz: !binary |-
6
+ MjA5NTk3MTgzMDk1MWJkNWQ3YzNjYzEyMTA3YzZhMGI5YTM1ZDkyOA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZDUxMTViZDcyNGFhZGZkN2JlYjAzMjQ3ZWU0NzI5NWRkZjY5Yzg1M2FlZjQ3
10
+ ZWNlNzg1OGFmYWNjZWZiOThiYjIyYWZlYzVhODFlNDUzZjIyZDMzNmY1NjQx
11
+ MjA4NWFhYjZiZjVlZGM3NjVhOWU1ZWFhNDBkZTk2YmM3YTNmNWQ=
12
+ data.tar.gz: !binary |-
13
+ YzIyYWIyYjY1ZjM2Yjc3NTkyM2ZhODBkYzRkZGFhYzgxYTZhNzQzNjM3Y2M5
14
+ MDgwZDNhMTczZDQ0OWI4MDBmMDQyZGE4MjZhMmU2ODMwNDIzMmNjYWNjMjJk
15
+ OTY3MzZkMDI1YTVkZWNhN2IxMTQ5ODIxZGRlZDI4Njc3YmVkOGE=
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -1,8 +1,13 @@
1
1
  language: ruby
2
+ addons:
3
+ postgresql: "9.2"
2
4
  rvm:
3
5
  - 1.9.3
4
- env:
5
- - POSTGIS=1.5
6
+ - 2.0
7
+ notifications:
8
+ recipients:
9
+ - mflorisson@cityway.fr
10
+ - ldonnet@cityway.fr
6
11
  before_install: ./travis/before_install.sh
7
12
  before_script:
8
13
  - ./travis/before_script.sh
data/Gemfile CHANGED
@@ -3,12 +3,18 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in activeroad.gemspec
4
4
  gemspec
5
5
 
6
- gem 'dr-postgis_adapter', :require => "postgis_adapter"
6
+ gem 'dr-postgis_adapter', :require => 'postgis_adapter'
7
+ gem 'coveralls', require: false
7
8
 
8
9
  group :development do
9
- gem 'rails-erd'
10
+ gem "rails-erd" # Tool to make schema class
10
11
  group :linux do
11
12
  gem 'rb-inotify', :require => RUBY_PLATFORM.include?('linux') && 'rb-inotify'
12
13
  gem 'rb-fsevent', :require => RUBY_PLATFORM.include?('darwin') && 'rb-fsevent'
13
14
  end
14
15
  end
16
+
17
+ group :development, :test do
18
+ gem "ruby-prof"
19
+ gem "bullet"
20
+ end
data/Guardfile CHANGED
@@ -2,8 +2,9 @@ guard 'bundler' do
2
2
  watch('Gemfile')
3
3
  end
4
4
 
5
- guard 'rspec', :version => 2, :notification => false, :bundler => true, :binstubs => false do
5
+ guard 'rspec', :notification => false do
6
6
  watch(%r{^spec/.+_spec\.rb$})
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
8
  watch('spec/spec_helper.rb') { "spec" }
8
9
 
9
10
  # Rails example
@@ -19,8 +20,3 @@ guard 'rspec', :version => 2, :notification => false, :bundler => true, :binstub
19
20
  watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
20
21
  end
21
22
 
22
- guard 'migrate' do
23
- watch(%r{^db/migrate/(\d+).+\.rb})
24
- watch('db/seeds.rb')
25
- end
26
-
data/README.md CHANGED
@@ -1,29 +1,89 @@
1
- # ActiveRoad [![Build Status](https://travis-ci.org/dryade/activeroad.png)](http://travis-ci.org/dryade/activeroad?branch=master) [![Dependency Status](https://gemnasium.com/dryade/activeroad.png)](https://gemnasium.com/dryade/activeroad) [![Code Climate](https://codeclimate.com/github/dryade/activeroad.png)](https://codeclimate.com/github/dryade/activeroad)
1
+ # ActiveRoad
2
+ [![Build Status](https://travis-ci.org/cityway-transdev/activeroad.png)](http://travis-ci.org/cityway-transdev/activeroad?branch=master) [![Dependency Status](https://gemnasium.com/cityway-transdev/activeroad.png)](https://gemnasium.com/cityway-transdev/activeroad) [![Code Climate](https://codeclimate.com/github/cityway-transdev/activeroad.png)](https://codeclimate.com/github/cityway-transdev/activeroad) [![Coverage Status](https://img.shields.io/coveralls/cityway-transdev/activeroad.svg)](https://coveralls.io/r/cityway-transdev/activeroad?branch=master)
2
3
 
3
- Rails engine with a model for roads and rails description
4
+ ActiveRoads is a rails engine with a specific models for transport networks. It allows to :
5
+ - import osm ways form openstreetmap datas (PBF file format)
6
+ - make an itinerary research
7
+ The goal of this project is not to make the faster itinerary search engine like [OSRM](http://map.project-osrm.org/) or [OpenTripPlanner](http://www.opentripplanner.org/) but the more flexible because it doesn't need to binarize datas.
4
8
 
5
9
  Requirements
6
10
  ------------
7
11
 
8
- This code has been run and tested on Ruby 1.9.3
12
+ This code has been run and tested on :
13
+ * Ruby 1.9.3 and ruby 2.0
14
+ * Postgresql 9.X
15
+ * Postgis 2.X
16
+
17
+ External Deps
18
+ -------------
19
+ On Debian/Ubuntu/Kubuntu OS :
20
+ ```sh
21
+ sudo apt-get install git postgresql postgis build-essential ruby-dev libproj-dev libgeos-dev libffi-dev zlib1g-dev libxslt1-dev libxml2-dev libbz2-dev libleveldb-dev libsnappy-dev
22
+ ```
9
23
 
10
24
  Installation
11
25
  ------------
12
26
 
13
27
  This package is available in RubyGems and can be installed with:
14
-
15
- gem install active_road
28
+ ```sh
29
+ gem install active_road
30
+ ```
16
31
 
17
32
  More Information
18
33
  ----------------
19
34
 
20
- More information can be found on the [project website on GitHub](http://github.com/dryade/activeroad).
21
- There is extensive usage documentation available [on the wiki](https://github.com/dryade/activeroad/wiki).
35
+ More information can be found on the [project website on GitHub](http://github.com/cityway-transdev/activeroad).
36
+ There is extensive usage documentation available [on the wiki](https://github.com/cityway-transdev/activeroad/wiki).
22
37
 
23
38
  Example Usage
24
39
  ------------
25
40
 
26
- ...
41
+ ### Import OSM ways
42
+
43
+ ```sh
44
+ bundle exec rake "app:active_road:import:osm_pbf_data[/home/user/test.osm.pbf]"
45
+
46
+ ```
47
+
48
+ ### Itinerary research
49
+
50
+ Example of basic finder :
51
+
52
+ Actually we can use only 4 transport modes :
53
+ * car
54
+ * train
55
+ * pedestrian
56
+ * bike
57
+
58
+ ```ruby
59
+ from = GeoRuby::SimpleFeatures::Point.from_x_y(-52.652771, 5.174379)
60
+ to = GeoRuby::SimpleFeatures::Point.from_x_y(-52.323182, 4.941829)
61
+ speed = 4 # In kilometer/hour
62
+ finder = ActiveRoad::ShortestPath::Finder.new(from, to, speed).tap do |finder|
63
+ finder.timeout = 30.seconds
64
+ end
65
+
66
+ # Get geometry
67
+ finder.geometry
68
+
69
+ # Get steps
70
+ finder.paths
71
+ ```
72
+
73
+ For a more complex query, you can use constraints arguments. It's an array of string which
74
+ describes :
75
+ * if we use conditionnal cost for a physical road Ex : ["car"]
76
+ * if we not use a physical road because it contains a specific conditionnal cost Ex : ["~car"]
77
+
78
+ ```ruby
79
+ from = GeoRuby::SimpleFeatures::Point.from_x_y(-52.652771, 5.174379)
80
+ to = GeoRuby::SimpleFeatures::Point.from_x_y(-52.323182, 4.941829)
81
+ speed = 50 # In kilometer/hour
82
+ constraints = ["car"]
83
+ finder = ActiveRoad::ShortestPath::Finder.new(from, to, speed, constraints).tap do |finder|
84
+ finder.timeout = 30.seconds
85
+ end
86
+ ```
27
87
 
28
88
  License
29
89
  -------
@@ -34,4 +94,4 @@ This project is licensed under the MIT license, a copy of which can be found in
34
94
  Support
35
95
  -------
36
96
 
37
- Users looking for support should file an issue on the GitHub issue tracking page (https://github.com/dryade/activeroad/issues), or file a pull request (https://github.com/dryade/activeroad/pulls) if you have a fix available.
97
+ Users looking for support should file an issue on the GitHub issue tracking page (https://github.com/cityway-transdev/activeroad/issues), or file a pull request (https://github.com/cityway-transdev/activeroad/pulls) if you have a fix available.
data/Rakefile CHANGED
@@ -5,13 +5,6 @@ rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
7
 
8
- namespace :ci do
9
- task :prepare do
10
- cp "config/database.yml.ci", "config/database.yml"
11
- end
12
- task :build => ["db:migrate", "spec"]
13
- end
14
-
15
8
  begin
16
9
  require 'rdoc/task'
17
10
  rescue LoadError
@@ -44,3 +37,11 @@ RSpec::Core::RakeTask.new(:rcov) do |t|
44
37
  end
45
38
 
46
39
  task :spec => "app:db:test:prepare"
40
+
41
+ namespace :ci do
42
+ task :prepare do
43
+ cp "config/database.yml.ci", "config/database.yml"
44
+ end
45
+ task :build => ["db:migrate", "spec"]
46
+ end
47
+
@@ -7,9 +7,12 @@ Gem::Specification.new do |s|
7
7
  s.version = ActiveRoad::VERSION
8
8
  s.authors = ["Alban Peignier", "Luc Donnet", "Marc Florisson"]
9
9
  s.email = ["alban@tryphon.eu", "luc.donnet@free.fr", "mflorisson@gmail.com"]
10
- s.homepage = ""
11
- s.summary = %q{Rails engine to manage roads and rails model}
12
- s.description = %q{Find street numbers and road ways}
10
+ s.homepage = "https://rubygems.org/gems/active_road"
11
+ s.summary = %q{Rails engine to import openstreetmap datas and make an itinerary research}
12
+ s.description = %q{Import openstreetmap datas and make an itinerary research}
13
+ s.required_ruby_version = '>= 1.9.3'
14
+ s.license = 'MIT'
15
+ #spec.requirements << 'libsnappy-dev, v6.0'
13
16
 
14
17
  s.files = `git ls-files`.split("\n")
15
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -19,20 +22,21 @@ Gem::Specification.new do |s|
19
22
  s.add_development_dependency "guard"
20
23
  s.add_development_dependency "guard-bundler"
21
24
  s.add_development_dependency "guard-rspec"
22
- s.add_development_dependency "guard-migrate"
23
- s.add_development_dependency "factory_girl_rails", "~> 4.2.1"
24
- s.add_development_dependency "rspec-rails", "~> 2.11.4"
25
- s.add_development_dependency 'rails', '~> 3.2.13'
25
+ s.add_development_dependency "factory_girl_rails", ">= 4.2.1"
26
+ s.add_development_dependency "rspec-rails", '~> 3.1.0'
27
+ s.add_development_dependency 'rails', '>=3.1.12'
26
28
 
27
- s.add_dependency 'activerecord'
29
+ s.add_dependency 'activerecord', '3.2.18'
28
30
  s.add_dependency 'activerecord-postgres-hstore'
29
- s.add_dependency 'dr-postgis_adapter', '0.8.1'
30
- s.add_dependency 'sqlite3', '~> 1.3.7'
31
- s.add_dependency 'pg', '~> 0.15.1'
32
- s.add_dependency 'activerecord-import', '~> 0.3.1'
33
- s.add_dependency 'georuby-ext', "0.0.2"
31
+ s.add_dependency 'dr-postgis_adapter', '0.8.4'
32
+ s.add_dependency 'pg', '>= 0.15.1'
33
+ s.add_dependency 'georuby-ext', "0.0.5"
34
34
  s.add_dependency 'nokogiri'
35
35
  s.add_dependency 'saxerator'
36
- s.add_dependency 'shortest_path', '0.0.3'
37
- s.add_dependency 'enumerize', '0.6.1'
36
+ s.add_dependency 'shortest_path', '0.0.4'
37
+ s.add_dependency 'enumerize', '0.7.0'
38
+ s.add_dependency "pbf_parser", '~> 0.0.6'
39
+ s.add_dependency "leveldb-native", '~> 0.6'
40
+ s.add_dependency "snappy"
41
+ s.add_dependency 'postgres-copy', '~> 0.6.O'
38
42
  end
@@ -14,8 +14,8 @@ class ActiveRoad::AccessLink
14
14
 
15
15
  alias_method :to_s, :name
16
16
 
17
- def self.from(location, constraints = {})
18
- ActiveRoad::AccessPoint.from(location, constraints).collect do |access_point|
17
+ def self.from(location)
18
+ ActiveRoad::AccessPoint.from(location).collect do |access_point|
19
19
  new :departure => location, :arrival => access_point
20
20
  end
21
21
  end
@@ -33,8 +33,8 @@ class ActiveRoad::AccessLink
33
33
 
34
34
  delegate :access_to_road?, :to => :arrival
35
35
 
36
- def paths(constraints = {})
37
- arrival.respond_to?(:paths) ? arrival.paths(constraints) : [arrival]
36
+ def paths
37
+ arrival.respond_to?(:paths) ? arrival.paths : [arrival]
38
38
  end
39
39
 
40
40
  def access_to_road?(road)
@@ -13,19 +13,15 @@ class ActiveRoad::AccessPoint
13
13
  end
14
14
 
15
15
  # Find access points from a location
16
- def self.from(location, constraints = {})
17
- physical_roads_filtered = ActiveRoad::PhysicalRoadFilter.new(constraints).filter
18
-
19
- physical_roads_filtered.nearest_to(location, 100).collect do |physical_road|
16
+ def self.from(location)
17
+ ActiveRoad::PhysicalRoad.nearest_to(location).collect do |physical_road|
20
18
  new :location => location, :physical_road => physical_road
21
19
  end
22
20
  end
23
21
 
24
22
  # Find access points to go to a location
25
- def self.to(location, constraints = {})
26
- physical_roads_filtered = ActiveRoad::PhysicalRoadFilter.new(constraints).filter
27
-
28
- physical_roads_filtered.nearest_to(location, 100).collect do |physical_road|
23
+ def self.to(location)
24
+ ActiveRoad::PhysicalRoad.nearest_to(location).collect do |physical_road|
29
25
  new :location => location, :physical_road => physical_road, :exit => true
30
26
  end
31
27
  end
@@ -41,7 +37,7 @@ class ActiveRoad::AccessPoint
41
37
  alias_method :geometry, :point_on_road
42
38
 
43
39
  def access_to_road?(road)
44
- physical_road == road
40
+ physical_road.id == road.id
45
41
  end
46
42
 
47
43
  def name
@@ -0,0 +1,41 @@
1
+ module ActiveRoad
2
+ class Boundary < ActiveRoad::Base
3
+ #set_table_name :boundaries
4
+ attr_accessible :objectid, :geometry, :name, :admin_level, :postal_code, :insee_code
5
+ acts_as_geom :geometry => :multi_polygon
6
+
7
+ # Return linear rings which delimit multi polygon area
8
+ def self.all_uniq_borders
9
+ borders = self.all.collect(&:geometry).collect(&:polygons).flatten(1).collect(&:rings).flatten(1).uniq
10
+ GeoRuby::SimpleFeatures::MultiLineString.from_line_strings(borders)
11
+ end
12
+
13
+ # Return linear rings which delimit multi polygon area
14
+ def borders
15
+ geometry.polygons.collect(&:rings).flatten
16
+ end
17
+
18
+ def intersection(other)
19
+ postgis_calculate(:intersection, [self, other])
20
+ end
21
+
22
+
23
+ def difference(other)
24
+ postgis_calculate(:difference, [self, other])
25
+ end
26
+
27
+ def sym_difference(other)
28
+ postgis_calculate(:symDifference, [self, other])
29
+ end
30
+
31
+ # Contains not take object equals on a boundary border!!
32
+ def self.first_contains(other)
33
+ where("ST_Contains(geometry, ST_GeomFromEWKT(E'#{other.as_hex_ewkb}'))").first
34
+ end
35
+
36
+ def self.all_intersect(other)
37
+ where("ST_Intersects(geometry, ST_GeomFromEWKT(E'#{other.as_hex_ewkb}'))")
38
+ end
39
+
40
+ end
41
+ end
@@ -1,6 +1,4 @@
1
1
  # A junction is a connection between 1 to n physical roads
2
- require "activerecord-postgres-hstore"
3
-
4
2
  module ActiveRoad
5
3
  class Junction < ActiveRoad::Base
6
4
  serialize :tags, ActiveRecord::Coders::Hstore
@@ -11,30 +9,18 @@ module ActiveRoad
11
9
  has_and_belongs_to_many :physical_roads, :class_name => "ActiveRoad::PhysicalRoad",:uniq => true
12
10
  has_many :junction_conditionnal_costs, :class_name => "ActiveRoad::JunctionConditionnalCost"
13
11
 
14
- %w[max_speed, max_slope].each do |key|
15
- attr_accessible key
16
- scope "has_#{key}", lambda { |value| where("properties @> hstore(?, ?)", key, value) }
17
- define_method(key) do
18
- properties && properties[key]
19
- end
20
-
21
- define_method("#{key}=") do |value|
22
- self.properties = (properties || {}).merge(key => value)
23
- end
24
- end
25
-
26
12
  def location_on_road(road)
27
13
  (@location_on_road ||= {})[road.id] ||= road.locate_point(geometry)
28
14
  end
29
15
 
30
- def paths(tags = {})
31
- ActiveRoad::PhysicalRoadFilter.new(tags, physical_roads).filter.includes(:junctions).collect do |physical_road|
16
+ def paths
17
+ physical_roads.includes(:junctions, :physical_road_conditionnal_costs).collect do |physical_road|
32
18
  ActiveRoad::Path.all self, (physical_road.junctions - [self]), physical_road
33
19
  end.flatten
34
20
  end
35
21
 
36
22
  def access_to_road?(road)
37
- physical_roads.include? road
23
+ physical_roads.pluck(:id).include? road.id
38
24
  end
39
25
 
40
26
  def to_geometry
@@ -42,7 +28,7 @@ module ActiveRoad
42
28
  end
43
29
 
44
30
  def to_s
45
- "Junction @#{geometry.to_lat_lng}"
31
+ "Junction @#{geometry.lng},#{geometry.lat}"
46
32
  end
47
33
 
48
34
  def name
@@ -1,5 +1,6 @@
1
1
  module ActiveRoad
2
2
  class JunctionConditionnalCost < ActiveRoad::Base
3
+ attr_accessible :tags, :cost, :start_physical_road, :end_physical_road
3
4
 
4
5
  belongs_to :junction
5
6
  belongs_to :start_physical_road, :class_name => 'ActiveRoad::PhysicalRoad', :foreign_key => 'start_physical_road_id'
@@ -7,6 +8,7 @@ module ActiveRoad
7
8
 
8
9
  validates_presence_of :junction_id
9
10
  validates_presence_of :tags
11
+ validates_uniqueness_of :tags
10
12
  validates_presence_of :cost
11
13
 
12
14
  end
@@ -0,0 +1,5 @@
1
+ module ActiveRoad
2
+ class JunctionsPhysicalRoad < ActiveRoad::Base
3
+
4
+ end
5
+ end
@@ -1,13 +1,14 @@
1
1
  module ActiveRoad
2
2
  class LogicalRoad < ActiveRoad::Base
3
3
  extend ActiveSupport::Memoizable
4
- attr_accessible :objectid, :name
5
-
6
- validates_uniqueness_of :objectid
4
+ attr_accessible :objectid, :name, :boundary_id
7
5
 
8
6
  has_many :physical_roads, :class_name => "ActiveRoad::PhysicalRoad", :inverse_of => :logical_road
9
-
10
7
  has_many :numbers, :through => :physical_roads, :class_name => "ActiveRoad::StreetNumber"
8
+ belongs_to :boundary, :class_name => "ActiveRoad::Boundary"
9
+
10
+ #validates_uniqueness_of :objectid
11
+ #validates :boundary, presence: true
11
12
 
12
13
  def geometry
13
14
  GeoRuby::SimpleFeatures::MultiLineString.from_line_strings physical_roads.map(&:geometry)
@@ -0,0 +1,293 @@
1
+ module ActiveRoad
2
+ module OsmPbfImporter
3
+
4
+ @@relation_required_tags_keys = ["boundary", "admin_level"]
5
+ @@relation_selected_tags_keys = ["boundary", "admin_level", "ref:INSEE", "name", "addr:postcode", "type"]
6
+ mattr_reader :relation_required_tags_keys
7
+ mattr_reader :relation_selected_tags_keys
8
+
9
+ @@way_required_tags_keys = ["highway", "railway", "boundary", "admin_level", "addr:housenumber"]
10
+ @@way_for_physical_road_required_tags_keys = ["highway", "railway"]
11
+ @@way_for_boundary_required_tags_keys = ["boundary", "admin_level"]
12
+ @@way_for_street_number_required_tags_keys = ["addr:housenumber"]
13
+ @@way_selected_tags_keys = [ "name", "maxspeed", "oneway", "boundary", "admin_level", "addr:housenumber" ]
14
+ # Add first_node_id and last_node_id
15
+ @@way_optionnal_tags_keys = ["highway", "maxspeed", "bridge", "tunnel", "toll", "cycleway", "cycleway-right", "cycleway-left", "cycleway-both", "oneway:bicycle", "oneway", "bicycle", "segregated", "foot", "lanes", "lanes:forward", "lanes:forward:bus", "busway:right", "busway:left", "oneway_bus", "boundary", "admin_level", "access", "construction", "junction", "motor_vehicle", "psv", "bus", "addr:city", "addr:country", "addr:state", "addr:street"]
16
+ mattr_reader :way_required_tags_keys
17
+ mattr_reader :way_for_physical_road_required_tags_keys
18
+ mattr_reader :way_for_boundary_required_tags_keys
19
+ mattr_reader :way_for_street_number_required_tags_keys
20
+ mattr_reader :way_selected_tags_keys
21
+ mattr_reader :way_optionnal_tags_keys
22
+
23
+ @@nodes_selected_tags_keys = [ "addr:housenumber", "addr:city", "addr:postcode", "addr:street" ]
24
+ mattr_reader :nodes_selected_tags_keys
25
+
26
+ @@pg_batch_size = 10000 # Not Rails.logger.debug a high value because postgres failed to allocate memory
27
+ mattr_reader :pg_batch_size
28
+
29
+ def self.included(base)
30
+ base.extend(ClassMethods)
31
+ end
32
+
33
+ module ClassMethods
34
+ end
35
+
36
+ def pedestrian?(tags)
37
+ highway_tag_values = %w{pedestrian footway path steps}
38
+ if tags["highway"].present? && highway_tag_values.include?(tags["highway"])
39
+ true
40
+ else
41
+ false
42
+ end
43
+ end
44
+
45
+ # http://wiki.openstreetmap.org/wiki/FR:Cycleway
46
+ # http://wiki.openstreetmap.org/wiki/FR:Bicycle
47
+ def bike?(tags)
48
+ highway_tag_values = %w{cycleway}
49
+ bike_tags_keys = ["cycleway:left", "cycleway:right", "cycleway", "cycleway:left"]
50
+
51
+ if (tags["highway"].present? && highway_tag_values.include?(tags["highway"])) || (bike_tags_keys & tags.keys).present?
52
+ true
53
+ else
54
+ false
55
+ end
56
+ end
57
+
58
+ # http://wiki.openstreetmap.org/wiki/Key:railway
59
+ def train?(tags)
60
+ railway_tag_values = %w{rail tram funicular light_rail subway}
61
+ if tags["railway"].present? && railway_tag_values.include?(tags["railway"])
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ # http://wiki.openstreetmap.org/wiki/FR:France_roads_tagging
69
+ def car?(tags)
70
+ highway_tag_values = %w{motorway trunk trunk_link primary secondary tertiary motorway_link primary_link unclassified service road residential track}
71
+ if tags["highway"].present? && highway_tag_values.include?(tags["highway"])
72
+ true
73
+ else
74
+ false
75
+ end
76
+ end
77
+
78
+ def required_way?(required_tags, tags)
79
+ required_tags.each do |require_tag_key|
80
+ if tags.keys.include?(require_tag_key)
81
+ return true
82
+ end
83
+ end
84
+ return false
85
+ end
86
+
87
+ def required_relation?(tags)
88
+ @@relation_required_tags_keys.each do |require_tag_key|
89
+ if tags.keys.include?(require_tag_key)
90
+ return true
91
+ end
92
+ end
93
+ return false
94
+ end
95
+
96
+ # Return an hash with tag_key => tag_value for osm attributes
97
+ def selected_tags(tags, selected_tags_keys)
98
+ {}.tap do |selected_tags|
99
+ tags.each do |key, value|
100
+ if selected_tags_keys.include?(key)
101
+ selected_tags[key] = value
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ # def extract_tag_value(tag_value)
108
+ # case tag_value
109
+ # when "yes" : 1
110
+ # when "no" : 0
111
+ # when /[0-9].+/i tag_value.to_f
112
+ # else 0
113
+ # end
114
+ # end
115
+
116
+ def physical_road_conditionnal_costs(way)
117
+ [].tap do |prcc|
118
+ prcc << [ "car", Float::MAX] if !way.car
119
+ prcc << [ "pedestrian", Float::MAX] if !way.pedestrian
120
+ prcc << [ "bike", Float::MAX] if !way.bike
121
+ prcc << [ "train", Float::MAX] if !way.train
122
+ end
123
+ end
124
+
125
+ def extract_relation_polygon(outer_geometries, inner_geometries = [])
126
+ outer_rings = join_ways(outer_geometries)
127
+ inner_rings = join_ways(inner_geometries)
128
+
129
+ # TODO : Fix the case where many outer rings with many inner rings
130
+ polygons = [].tap do |polygons|
131
+ outer_rings.each { |outer_ring|
132
+ polygons << GeoRuby::SimpleFeatures::Polygon.from_linear_rings( [outer_ring] + inner_rings )
133
+ }
134
+ end
135
+ end
136
+
137
+ def join_ways(ways)
138
+ closed_ways = []
139
+ endpoints_to_ways = EndpointToWayMap.new
140
+ for way in ways
141
+ if way.closed?
142
+ closed_ways << way
143
+ next
144
+ end
145
+
146
+ # Are there any existing ways we can join this to?
147
+ to_join_to = endpoints_to_ways.get_from_either_end(way)
148
+ if to_join_to.present?
149
+ joined = way
150
+ for existing_way in to_join_to
151
+ joined = join_way(joined, existing_way)
152
+ endpoints_to_ways.remove_way(existing_way)
153
+ if joined.closed?
154
+ closed_ways << joined
155
+ break
156
+ end
157
+ end
158
+
159
+ if !joined.closed?
160
+ endpoints_to_ways.add_way(joined)
161
+ end
162
+ else
163
+ endpoints_to_ways.add_way(way)
164
+ end
165
+ end
166
+
167
+ if endpoints_to_ways.number_of_endpoints != 0
168
+ raise StandardError, "Unclosed boundaries"
169
+ end
170
+
171
+ closed_ways
172
+ end
173
+
174
+ def join_way(way, other)
175
+ if way.closed?
176
+ raise StandardError, "Trying to join a closed way to another"
177
+ end
178
+ if other.closed?
179
+ raise StandardError, "Trying to join a way to a closed way"
180
+ end
181
+
182
+ if way.points.first == other.points.first
183
+ new_points = other.reverse.points[0..-2] + way.points
184
+ elsif way.points.first == other.points.last
185
+ new_points = other.points[0..-2] + way.points
186
+ elsif way.points.last == other.points.first
187
+ new_points = way.points[0..-2] + other.points
188
+ elsif way.points.last == other.points.last
189
+ new_points = way.points[0..-2] + other.reverse.points
190
+ else
191
+ raise StandardError, "Trying to join two ways with no end point in common"
192
+ end
193
+
194
+ GeoRuby::SimpleFeatures::LineString.from_points(new_points)
195
+ end
196
+
197
+ class EndpointToWayMap
198
+ attr_accessor :endpoints
199
+
200
+ def initialize
201
+ @endpoints = {}
202
+ end
203
+
204
+ def add_way(way)
205
+ if get_from_either_end(way).present?
206
+ raise StandardError, "Call to add_way would overwrite existing way(s)"
207
+ end
208
+ self.endpoints[way.points.first] = way
209
+ self.endpoints[way.points.last] = way
210
+ end
211
+
212
+ def remove_way(way)
213
+ endpoints.delete(way.points.first)
214
+ endpoints.delete(way.points.last)
215
+ end
216
+
217
+ def get_from_either_end(way)
218
+ [].tap do |selected_end_points|
219
+ selected_end_points << endpoints[way.points.first] if endpoints.include?(way.points.first)
220
+ selected_end_points << endpoints[way.points.last] if endpoints.include?(way.points.last)
221
+ end
222
+ end
223
+
224
+ def number_of_endpoints
225
+ return endpoints.size
226
+ end
227
+
228
+ end
229
+
230
+ class Node
231
+ attr_accessor :id, :lon, :lat, :ways, :end_of_way, :addr_housenumber, :tags
232
+
233
+ def initialize(id, lon, lat, addr_housenumber = "", ways = [], end_of_way = false, tags = {} )
234
+ @id = id
235
+ @lon = lon
236
+ @lat = lat
237
+ @addr_housenumber = addr_housenumber
238
+ @ways = ways
239
+ @end_of_way = end_of_way
240
+ @tags = tags
241
+ end
242
+
243
+ def add_way(id)
244
+ @ways << id
245
+ end
246
+
247
+ def marshal_dump
248
+ [@id, @lon, @lat, @addr_housenumber, @ways, @end_of_way, @tags]
249
+ end
250
+
251
+ def marshal_load array
252
+ @id, @lon, @lat, @addr_housenumber, @ways, @end_of_way, @tags = array
253
+ end
254
+
255
+ def used?
256
+ ( ways.present? && ways.size > 1 ) || end_of_way
257
+ end
258
+ end
259
+
260
+ class Way
261
+ attr_accessor :id, :nodes, :car, :bike, :train, :pedestrian, :name, :maxspeed, :oneway, :boundary, :admin_level, :addr_housenumber, :options
262
+
263
+ def initialize(id, nodes = [], car = false, bike = false, train = false, pedestrian = false, name = "", maxspeed = 0, oneway = false, boundary = "", admin_level = "", addr_housenumber = "", options = {})
264
+ @id = id
265
+ @nodes = nodes
266
+ @car = car
267
+ @bike = bike
268
+ @train = train
269
+ @pedestrian = pedestrian
270
+ @name = name
271
+ @maxspeed = maxspeed
272
+ @oneway = oneway
273
+ @boundary = boundary
274
+ @admin_level = admin_level
275
+ @addr_housenumber = addr_housenumber
276
+ @options = options
277
+ end
278
+
279
+ def add_node(id)
280
+ @nodes << id
281
+ end
282
+
283
+ def marshal_dump
284
+ [@id, @nodes, @car, @bike, @train, @pedestrian, @name, @maxspeed, @oneway, @boundary, @admin_level, @addr_housenumber, @options]
285
+ end
286
+
287
+ def marshal_load array
288
+ @id, @nodes, @car, @bike, @train, @pedestrian, @name, @maxspeed, @oneway, @boundary, @admin_level, @addr_housenumber, @options = array
289
+ end
290
+ end
291
+
292
+ end
293
+ end