Skip to content

Commit dba6f0e

Browse files
committed
separates the geojson attribute from geojson representations #50
- #geojson and #geojson= are used for reading / changing the geometry - #as_geojson(...) to be used to get a geojson representation (optionally of the whole record or only including selected attributes) - adds geojson conversion methods for scopes and issue arrays #50
1 parent 753e8f3 commit dba6f0e

16 files changed

+132
-78
lines changed

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(simple: true)
24+
api.geojson issue.geojson
2525
else
2626
api.geojson ""
2727
end
Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
1-
<% return '' if @project.nil? %>
2-
<% return '' unless User.current.allowed_to?(:view_issues, @project) %>
1+
<% if @project and @project.module_enabled?(:gtt) %>
32

4-
<% if @project.nil? or @project.module_enabled?(:gtt) %>
53
<fieldset id="location" class="collapsible">
64
<legend onclick="toggleFieldset(this);"><%= l(:field_location) %></legend>
75

8-
<%= tag(:div, :data => {
9-
# TODO: Don't know where to extend "Issues"
10-
:geom => IssuesHelper.get_geojson(@issues),
11-
:bounds => @project.geojson,
12-
:layers => @project.gtt_tile_sources,
13-
:popup => {
14-
:href => '/issues/[id]'
15-
}
16-
}, :id => 'ol-' + rand(36**8).to_s(36), :class => 'ol-map')
17-
%>
6+
<%= map_tag map: @project.map, geom: Issue.array_to_geojson(@issues, include_properties: { only: %i(id subject) }), popup: { href: '/issues/[id]' } %>
187
</fieldset>
8+
199
<% end %>

app/views/issues/show.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ api.issue do
2424
end
2525

2626
if @issue.geom
27-
api.geojson @issue.geojson(simple: true)
27+
api.geojson @issue.geojson
2828
else
2929
api.geojson ""
3030
end

app/views/projects/index.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ api.array :projects, api_meta(:total_count => @project_count, :offset => @offset
1010
api.is_public project.is_public?
1111

1212
if project.geom
13-
api.geojson project.geojson(simple: true)
13+
api.geojson project.geojson
1414
else
1515
api.geojson ""
1616
end

app/views/projects/show.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ api.project do
99
api.is_public @project.is_public?
1010

1111
if @project.geom
12-
api.geojson @project.geojson(simple: true)
12+
api.geojson @project.geojson
1313
else
1414
api.geojson ""
1515
end

app/views/users/index.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ api.array :users, api_meta(:total_count => @user_count, :offset => @offset, :lim
1010
api.last_login_on user.last_login_on
1111

1212
if user.geom
13-
api.geojson user.geojson(simple: true)
13+
api.geojson user.geojson
1414
else
1515
api.geojson ""
1616
end

app/views/users/show.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ api.user do
1010
api.status @user.status if User.current.admin?
1111

1212
if @user.geom
13-
api.geojson @user.geojson(simple: true)
13+
api.geojson @user.geojson
1414
else
1515
api.geojson ""
1616
end

lib/redmine_gtt/conversions.rb

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,36 @@ module RedmineGtt
99
# between.
1010
module Conversions
1111

12+
class WkbToJson
13+
def initialize()
14+
@factory = RGeo::GeoJSON::EntityFactory.instance
15+
@parser = RGeo::WKRep::WKBParser.new(
16+
support_ewkb: true,
17+
default_srid: 4326
18+
)
19+
end
20+
21+
def to_json(wkb, id: nil, properties: nil)
22+
RGeo::GeoJSON.encode feature(wkb, id, properties)
23+
end
24+
25+
def collection_to_json(data)
26+
RGeo::GeoJSON.encode @factory.feature_collection(
27+
data.map{|wkb, id, props| feature wkb, id, props}
28+
)
29+
end
30+
31+
private
32+
33+
def feature(wkb, id, properties = nil)
34+
@factory.feature @parser.parse(wkb), id, (properties || {})
35+
end
36+
37+
end
38+
1239
# Turns database WKB into geometry attribute string
13-
def self.wkb_to_json(wkb, id: nil, properties: {})
14-
factory = RGeo::GeoJSON::EntityFactory.instance
15-
geometry = RGeo::WKRep::WKBParser.new(
16-
support_ewkb: true,
17-
default_srid: 4326
18-
).parse(wkb)
19-
RGeo::GeoJSON.encode factory.feature(geometry, id, properties)
40+
def self.wkb_to_json(wkb, id: nil, properties: nil)
41+
WkbToJson.new.to_json(wkb, id: id, properties: properties)
2042
end
2143

2244
# Turn geometry attribute string into WKB for database use

lib/redmine_gtt/patches/geojson_attribute.rb

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,55 @@ module Patches
44
# adds wkb/geojson conversion logic to the class it's included in
55
module GeojsonAttribute
66

7-
def geojson_additional_properties
8-
as_json except: [:geom]
7+
def self.prepended(base)
8+
base.extend ClassMethods
9+
base.class_eval do
10+
scope :geojson, ->(include_properties: false){
11+
data = []
12+
where.not(geom: nil).
13+
find_in_batches.each{|group| group.each{|o|
14+
data << o.geojson_params(include_properties)
15+
}}
16+
Conversions::WkbToJson.new.collection_to_json data
17+
}
18+
end
919
end
1020

11-
# use simple: true to skip inclusion of record's properties
12-
def geojson(simple: false)
13-
@geojson ||= if geom.present?
14-
Conversions.wkb_to_json(
15-
geom,
16-
id: id,
17-
properties: (simple ? {} : geojson_additional_properties)
21+
module ClassMethods
22+
def array_to_geojson(array, include_properties: false)
23+
Conversions::WkbToJson.new.collection_to_json(
24+
array.map{ |o|
25+
o.geojson_params(include_properties) if o.geom
26+
}.compact
1827
)
1928
end
2029
end
2130

31+
def geojson_additional_properties(include_properties = false)
32+
case include_properties
33+
when Hash
34+
if only = include_properties[:only]
35+
as_json only: only
36+
else
37+
except = include_properties[:except] || []
38+
except << :geom
39+
as_json except: except
40+
end
41+
when TrueClass
42+
as_json except: [:geom]
43+
else
44+
{}
45+
end
46+
end
47+
48+
# returns the geojson attribute for reading / writing to the DB
49+
def geojson
50+
@geojson ||= if geom.present?
51+
Conversions.wkb_to_json geom
52+
end
53+
end
54+
55+
# sets the geojson attribute for reading / writing to the DB
2256
def geojson=(geometry)
2357
@geojson = geometry
2458
if (geometry.present?)
@@ -28,6 +62,29 @@ def geojson=(geometry)
2862
end
2963
end
3064

65+
# returns a GeoJSON representation of this record.
66+
#
67+
# Use include_properties: true to include all of the record's properties
68+
# use include_properties: { only: [ :id, :subject ] } for a specific
69+
# subset of properties
70+
#
71+
# Use this method and not #geojson for rendering maps
72+
def as_geojson(include_properties: false)
73+
return geojson unless include_properties
74+
75+
if geom.present?
76+
Conversions.wkb_to_json(
77+
geom,
78+
id: id,
79+
properties: geojson_additional_properties(include_properties)
80+
)
81+
end
82+
end
83+
84+
def geojson_params(include_properties)
85+
[ geom, id, geojson_additional_properties(include_properties) ]
86+
end
87+
3188
end
3289
end
3390
end

lib/redmine_gtt/patches/issue_patch.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ def self.apply
1818
end
1919

2020
def map
21-
GttMap.new json: geojson, layers: project.gtt_tile_sources,
22-
bounds: (new_record? ? project.map.json : geojson(simple: true))
21+
json = as_geojson
22+
GttMap.new json: json, layers: project.gtt_tile_sources,
23+
bounds: (new_record? ? project.map.json : json)
2324
end
2425

2526
end

0 commit comments

Comments
 (0)