Skip to content

Commit 9e047dc

Browse files
committed
Merge branch 'develop' into 'master'
Develop See merge request gtt/redmine_gtt!17
2 parents 8e83913 + 1d95927 commit 9e047dc

File tree

14 files changed

+151
-21
lines changed

14 files changed

+151
-21
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ gem 'immutable-struct'
55
gem "rgeo"
66
gem "rgeo-geojson"
77
gem "rgeo-activerecord"
8-
gem "pg"
8+
gem "pg", "~> 0.15" # make sure we use a version compatible with AR
99
gem 'activerecord-postgis-adapter', '~> 3.1'

app/views/issues/index.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ api.array :issues, api_meta(:total_count => @issue_count, :offset => @offset, :l
2121
api.estimated_hours issue.estimated_hours
2222

2323
if issue.geom
24-
api.geojson issue.geojson
24+
api.geojson issue.geojson.to_json
2525
else
2626
api.geojson ""
2727
end

app/views/projects/index.api.rsb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ api.array :projects, api_meta(:total_count => @project_count, :offset => @offset
99
api.status project.status
1010
api.is_public project.is_public?
1111

12-
if project.geom
13-
api.geojson project.geojson
14-
else
15-
api.geojson ""
12+
if @include_geometry
13+
if project.geom
14+
api.geojson project.geojson.to_json
15+
else
16+
api.geojson ""
17+
end
1618
end
1719

1820
render_api_custom_values project.visible_custom_field_values, api

init.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
author 'Georepublic'
66
author_url 'https://hub.georepublic.net/gtt/redmine_gtt'
77
description 'Adds location-based task management and maps'
8-
version '0.9.1'
8+
version '1.0.0'
99

1010
requires_redmine :version_or_higher => '3.4.0'
1111

lib/redmine_gtt/conversions.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ def call(wkb)
4848
end
4949
end
5050

51+
def self.to_feature(geometry, properties: {})
52+
geometry = JSON.parse geometry if geometry.is_a?(String)
53+
{
54+
'type' => 'Feature',
55+
'geometry' => geometry,
56+
'properties' => properties
57+
}
58+
end
5159

5260
# Turns database WKB into geometry attribute string
5361
def self.wkb_to_json(wkb, id: nil, properties: nil)

lib/redmine_gtt/patches/geojson_attribute.rb

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,26 @@ module GeojsonAttribute
77
def self.prepended(base)
88
base.extend ClassMethods
99
base.class_eval do
10+
# if this wouldnt break count, this would be really nice:
11+
#default_scope ->{ select "#{table_name}.*, ST_AsGeoJson(#{table_name}.geom) as geojson" }
1012
scope :geojson, ->(include_properties: false){
1113
data = []
1214
where.not(geom: nil).
13-
find_in_batches.each{|group| group.each{|o|
15+
select("#{table_name}.*, #{geojson_attribute_select}").
16+
find_each{|o|
1417
data << o.geojson_params(include_properties)
15-
}}
18+
}
1619
Conversions::GeomToJson.new.collection_to_json data
1720
}
1821
end
1922
end
2023

2124
module ClassMethods
25+
26+
def geojson_attribute_select
27+
"ST_AsGeoJson(#{table_name}.geom) as db_geojson"
28+
end
29+
2230
def array_to_geojson(array, include_properties: false)
2331
Conversions::GeomToJson.new.collection_to_json(
2432
array.map{ |o|
@@ -47,9 +55,12 @@ def geojson_additional_properties(include_properties = false)
4755

4856
# returns the geojson attribute for reading / writing to the DB
4957
def geojson
50-
@geojson ||= if geom.present?
51-
Conversions.geom_to_json geom
52-
end
58+
@geojson ||= if respond_to?(:db_geojson) && db_geojson.present?
59+
# use the value returned by ST_AsGeoJson
60+
Conversions.to_feature db_geojson
61+
elsif geom.present?
62+
Conversions.geom_to_json geom
63+
end
5364
end
5465

5566
# sets the geojson attribute for reading / writing to the DB

lib/redmine_gtt/patches/issue_patch.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ def self.apply
77
unless Issue < self
88
Issue.prepend self
99
Issue.prepend GeojsonAttribute
10+
Issue.extend ClassMethods
1011
Issue.class_eval do
1112
attr_reader :distance
1213
safe_attributes "geojson",
1314
if: ->(issue, user){
1415
perm = issue.new_record? ? :add_issues : :edit_issues
1516
user.allowed_to? perm, issue.project
1617
}
18+
1719
end
1820
end
1921
end
@@ -24,6 +26,23 @@ def map
2426
bounds: (new_record? ? project.map.json : json)
2527
end
2628

29+
module ClassMethods
30+
def load_geojson(issues)
31+
if issues.any?
32+
geometries_by_id = Hash[
33+
Issue.
34+
where(id: issues.map(&:id)).
35+
pluck(:id, Issue.geojson_attribute_select)
36+
]
37+
issues.each do |issue|
38+
issue.instance_variable_set(
39+
"@geojson", Conversions.to_feature(geometries_by_id[issue.id])
40+
)
41+
end
42+
end
43+
end
44+
end
45+
2746
end
2847

2948
end

lib/redmine_gtt/patches/issue_query_patch.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
module RedmineGtt
24
module Patches
35
module IssueQueryPatch
@@ -13,6 +15,9 @@ def self.prepended(base)
1315

1416
def issues(*_)
1517
super.tap do |issues|
18+
if load_geojson? || has_column?(:geom)
19+
Issue.load_geojson(issues)
20+
end
1621
if center = find_center_point
1722
load_distances(issues, center)
1823
end
@@ -21,6 +26,13 @@ def issues(*_)
2126
raise ::Query::StatementInvalid.new(e.message)
2227
end
2328

29+
def load_geojson
30+
@load_geojson = true
31+
end
32+
def load_geojson?
33+
!!@load_geojson
34+
end
35+
2436
def available_columns
2537
return @available_columns if @available_columns
2638

@@ -75,7 +87,7 @@ def sql_for_distance_field(field, operator, value)
7587
# or ['meters_min', 'meters_max', 'lng', 'lat'] if op == '><'
7688
lng, lat = value.last(2).map(&:to_f)
7789
distance = value.first.to_i
78-
sql = "ST_Distance_Sphere(#{Issue.table_name}.geom, ST_GeomFromText('POINT(#{lng} #{lat})',4326))"
90+
sql = +"ST_Distance_Sphere(#{Issue.table_name}.geom, ST_GeomFromText('POINT(#{lng} #{lat})',4326))"
7991
if operator == '><'
8092
distance_max = value[1].to_i
8193
sql << " BETWEEN #{distance} AND #{distance_max}"

lib/redmine_gtt/patches/issues_controller_patch.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ def show
2222
end
2323
end
2424

25+
def retrieve_query(*_)
26+
return @query if @query
27+
super
28+
end
29+
private :retrieve_query
2530

2631
def index
2732
retrieve_query
@@ -36,6 +41,7 @@ def index
3641
:filename => "issues.geojson"
3742
)
3843
}
44+
format.api { @query.load_geojson; super }
3945
format.any { super }
4046
end
4147
else

lib/redmine_gtt/patches/projects_controller_patch.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ def self.apply
1010
def index
1111
respond_to do |format|
1212
format.api {
13-
scope = RedmineGtt::SpatialProjectsQuery.new(
13+
@include_geometry = params[:include] == 'geometry'
14+
query = RedmineGtt::SpatialProjectsQuery.new(
1415
contains: params[:contains],
16+
geometry: @include_geometry,
1517
projects: Project.visible.sorted
16-
).scope
17-
@project_count = scope.count
18+
)
19+
scope = query.scope
20+
@project_count = query.count
1821
@offset, @limit = api_offset_and_limit
1922
@projects = scope.offset(@offset).limit(@limit).to_a
2023
}

0 commit comments

Comments
 (0)