Merge lp:~zack-krejci/healthscapes/trunk into lp:healthscapes/trunk

Proposed by Zack
Status: Merged
Merged at revision: 12
Proposed branch: lp:~zack-krejci/healthscapes/trunk
Merge into: lp:healthscapes/trunk
Diff against target: 732 lines (+488/-38)
10 files modified
controllers/gis.py (+1/-0)
controllers/lit.py (+40/-0)
controllers/sources.py (+27/-0)
controllers/tool.py (+1/-1)
models/lit.py (+25/-0)
modules/geo/func.py (+7/-3)
static/scripts/hs/hs_base.js (+5/-2)
static/scripts/hs/panels/tool_panel.js (+22/-10)
tool/aggregate.py (+4/-2)
views/gis/hs.html (+356/-20)
To merge this branch: bzr merge lp:~zack-krejci/healthscapes/trunk
Reviewer Review Type Date Requested Status
nicopresto Pending
Review via email: mp+49117@code.launchpad.net
To post a comment you must log in.
lp:~zack-krejci/healthscapes/trunk updated
13. By <email address hidden>

Geoserver url is now dynamic

14. By <email address hidden>

Added Lit Tool, Wiki, NPR API

15. By <email address hidden>

Fixed geoserver url

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'controllers/gis.py'
2--- controllers/gis.py 2011-02-04 20:12:08 +0000
3+++ controllers/gis.py 2011-02-12 21:37:13 +0000
4@@ -1983,6 +1983,7 @@
5
6 def hs():
7 output=geoexplorer()
8+ output.update ({'geoserver': deployment_settings.geoserver})
9 output.update ({'tool_list': load_tools (), 'tool_saved_results': load_results (), 'tool_saved_analyses': load_analyses ()})
10 return(output)
11
12
13=== added file 'controllers/lit.py'
14--- controllers/lit.py 1970-01-01 00:00:00 +0000
15+++ controllers/lit.py 2011-02-12 21:37:13 +0000
16@@ -0,0 +1,40 @@
17+import simplejson as json
18+
19+def kw():
20+ from BeautifulSoup import BeautifulStoneSoup
21+ from urllib2 import urlopen
22+
23+ tmp_create_lit ()
24+ disease = request.vars.get ('d')
25+ result = db.executesql ('''
26+ SELECT keyword.kw, counts.count
27+ FROM (SELECT keycount.kw_id, keycount.count
28+ FROM (SELECT id
29+ FROM disease
30+ WHERE d = 'malaria') AS diseases
31+ INNER JOIN keycount
32+ ON keycount.d_id = diseases.id) AS counts
33+ INNER JOIN keyword
34+ ON keyword.id = counts.kw_id;
35+ ''')
36+ rList = []
37+ capabilities = urlopen (deployment_settings.geoserver.url + '/wms?SERVICE=WMS&REQUEST=GetCapabilities').read ()
38+ soup = BeautifulStoneSoup (capabilities)
39+ keywords = soup.findAll (name = 'keyword')
40+ for r in result:
41+ words = []
42+ for k in keywords:
43+ if k.text == r[0]:
44+ words.append (k)
45+ mapList = []
46+ for w in words:
47+ layer = w.parent.parent
48+ id = layer.find ('name').text
49+ name = layer.find ('title').text
50+ mapList.append ({'id': id, 'name': name})
51+ d = dict (kw = r[0], count = r[1], numMaps = len (words), maps = mapList)
52+ rList.append (d)
53+ return json.dumps (rList)
54+
55+def map():
56+ pass
57
58=== added file 'controllers/sources.py'
59--- controllers/sources.py 1970-01-01 00:00:00 +0000
60+++ controllers/sources.py 2011-02-12 21:37:13 +0000
61@@ -0,0 +1,27 @@
62+import simplejson as json
63+
64+def index():
65+ return {}
66+
67+def wiki():
68+ from urllib2 import urlopen, Request
69+ from re import sub
70+
71+ disease = request.vars.get ('disease')
72+
73+ r = Request ('http://en.wikipedia.org/w/index.php?action=render&title=%s' % (disease,), headers = {'User-Agent': 'Healthscapes'})
74+ result = urlopen (r)
75+ html = result.read ()
76+ return sub ('(<table class\=\"infobox[^>]*style=")', '\\1float: left; margin-right: 10px;', html)
77+
78+
79+def npr():
80+ from urllib2 import urlopen
81+
82+ disease = request.vars.get ('disease')
83+
84+ result = urlopen ('http://api.npr.org/query?apiKey=' + deployment_settings.npr_key +'&fields=title,teaser&output=JSON&searchTerm=%s' % (disease,))
85+
86+ return result.read ()
87+
88+
89
90=== modified file 'controllers/tool.py'
91--- controllers/tool.py 2011-02-04 20:12:08 +0000
92+++ controllers/tool.py 2011-02-12 21:37:13 +0000
93@@ -85,7 +85,7 @@
94 return json.dumps ({'err': 'Bad filename'})
95 mod = get_tool (tool_ob['id'])
96 pairs = []
97- for ob in mod.cargs:
98+ for ob in mod['args']:
99 key = ob[0]
100 pairs.append ((key, request.vars.get (key)))
101 val = json.dumps (dict (pairs))
102
103=== added file 'models/lit.py'
104--- models/lit.py 1970-01-01 00:00:00 +0000
105+++ models/lit.py 2011-02-12 21:37:13 +0000
106@@ -0,0 +1,25 @@
107+db.define_table('keyword',
108+ Field('kw'),
109+)
110+
111+db.define_table('disease',
112+ Field('d'),
113+)
114+
115+db.define_table('keycount',
116+ Field('kw_id', db.keyword),
117+ Field('d_id', db.disease),
118+ Field('count','integer'),
119+)
120+
121+def tmp_create_lit ():
122+ db.keyword.truncate ()
123+ db.disease.truncate ()
124+ db.keycount.truncate ()
125+ m_key = db.keyword.insert (kw ='malaria')
126+ p_key = db.keyword.insert (kw = 'precipitation')
127+ s_key = db.keyword.insert (kw = 'spearfish')
128+ m = db.disease.insert (d = 'malaria')
129+ db.keycount.insert (kw_id = m_key, d_id = m, count = 100)
130+ db.keycount.insert (kw_id = p_key, d_id = m, count = 67)
131+ db.keycount.insert (kw_id = s_key, d_id = m, count = 42)
132
133=== modified file 'modules/geo/func.py'
134--- modules/geo/func.py 2011-01-24 22:39:23 +0000
135+++ modules/geo/func.py 2011-02-12 21:37:13 +0000
136@@ -16,14 +16,17 @@
137 else:
138 return arg
139
140-def makeCount (src):
141+'''def makeCount (src):
142 def COUNT (*args):
143 count = 0
144 for a in args:
145 if a == src:
146 count += 1
147 return count
148- return COUNT
149+ return COUNT'''
150+
151+def COUNT (*args):
152+ return len (args)
153
154 def MIN (*args):
155 return min (args)
156@@ -42,7 +45,8 @@
157 elif name == 'NONZERO':
158 return NONZERO
159 elif name == 'COUNT':
160- return makeCount (*args)
161+ #return makeCount (*args)
162+ return COUNT
163 elif name == 'MIN':
164 return MIN
165 elif name == 'MAX':
166
167=== modified file 'static/scripts/hs/hs_base.js'
168--- static/scripts/hs/hs_base.js 2011-02-04 20:12:08 +0000
169+++ static/scripts/hs/hs_base.js 2011-02-12 21:37:13 +0000
170@@ -1,6 +1,9 @@
171 var hs = {
172- geoserver: function (mapname) {
173- return 'http://zk.healthscapes.org/geoserver/wfs?request=DescribeFeatureType&typename=hsd:' + mapname + '&version=1.1.0';
174+ geoserver: {
175+ url: geoserver_url,
176+ describe: function (mapname) {
177+ return hs.geoserver.url + '/wfs?request=DescribeFeatureType&typename=hsd:' + mapname + '&version=1.1.0';
178+ }
179 },
180 application: 'healthscapes',
181 /*SelectBox: Ext.extend (Ext.Panel, {
182
183=== modified file 'static/scripts/hs/panels/tool_panel.js'
184--- static/scripts/hs/panels/tool_panel.js 2011-02-04 20:55:45 +0000
185+++ static/scripts/hs/panels/tool_panel.js 2011-02-12 21:37:13 +0000
186@@ -369,6 +369,7 @@
187 var method = 'mean'
188 var groups = [];
189 var thisWindow = this;
190+ var aggPanel;
191
192 this.getValue = function () {
193 return aggPanel.json ();
194@@ -392,7 +393,7 @@
195 }
196
197 var store = new GeoExt.data.AttributeStore ({
198- url: hs.geoserver (mapname)
199+ url: hs.geoserver.describe (mapname)
200 });
201 store.load ();
202
203@@ -471,6 +472,7 @@
204 groupCount ++;
205
206 this.json = function () {
207+ console.log (fieldType.getValue ());
208 var ob = {
209 name: this.name,
210 output: output.getValue (),
211@@ -709,7 +711,7 @@
212 }
213 this.setValue (map_ob.name);
214 store = new GeoExt.data.AttributeStore ({
215- url: hs.geoserver (map_ob.id)
216+ url: hs.geoserver.describe (map_ob.id)
217 });
218 store.load ();
219 };
220@@ -794,23 +796,33 @@
221 }),
222 Agg: Ext.extend (Ext.Button, {
223 constructor: function (label, mapSource, config) {
224+ var map;
225 var w;
226
227 this.getValue = function () {
228 //if (preset)
229 //return JSON.stringify (preset);
230- if (w)
231- return w.getValue ();
232+ console.log ('val', w.getValue ());
233+ if (w) {
234+ return JSON.stringify ({
235+ map: map,
236+ data: w.getValue (),
237+ });
238+ }
239 else
240- return {};
241+ return '{}';
242 };
243
244 var thisValue = this;
245
246 this.setField = function (ob) {
247 var preset = JSON.parse (ob);
248- w = new hs.tool.Agg.Window ('br_precip');
249- w.setField (preset);
250+ map = preset.map;
251+ data = JSON.parse (preset.data);
252+ w = new hs.tool.Agg.Window (map.id);
253+ w.setField (data);
254+ w.show ();
255+ w.hide ();
256 };
257
258 if (!config) config = {}
259@@ -818,11 +830,11 @@
260 fieldLabel: label,
261 text: 'Configure',
262 handler: function (event) {
263- var mapname = mapSource.getValue ();
264- if (!mapname)
265+ map = JSON.parse (mapSource.getValue ());
266+ if (!map)
267 return;
268 if (!w)
269- w = new hs.tool.Agg.Window (mapname);
270+ w = new hs.tool.Agg.Window (map.id);
271 w.show ();
272 },
273 });
274
275=== modified file 'tool/aggregate.py'
276--- tool/aggregate.py 2011-01-24 22:39:23 +0000
277+++ tool/aggregate.py 2011-02-12 21:37:13 +0000
278@@ -42,14 +42,16 @@
279 keys = {}
280 output = []
281
282- for inst in attr['agg']:
283+ aggSource = attr['agg']['map']
284+ dataSource = attr['agg']['data']
285+ for inst in dataSource:
286 dst = keygen (inst['name'])
287 if inst['output']:
288 output.append (dst)
289 for poly in polygons:
290 keys[(None, inst['name'])] = dst
291 src = keymap (keys, inst['data'])
292- func = get (str (inst ['method']))
293+ func = get (str (inst ['method']), attr['points'])
294 if inst['dir'] == 'extern':
295 mode = enum.MANY_TO_ONE
296 else:
297
298=== modified file 'views/gis/hs.html'
299--- views/gis/hs.html 2011-02-04 20:12:08 +0000
300+++ views/gis/hs.html 2011-02-12 21:37:13 +0000
301@@ -44,6 +44,9 @@
302 {{pass}}
303
304 <script language="javascript" type="text/javascript" src="/{{=request.application}}/static/scripts/edit_area/edit_area_full.js"></script>
305+<script type="text/javascript">
306+ var geoserver_url = '{{=geoserver.url}}';
307+</script>
308 <script type="text/javascript" src="/{{=request.application}}/static/scripts/hs/hs_base.js"></script>
309 <script type="text/javascript" src="/{{=request.application}}/static/scripts/hs/panels/tool_panel.js"></script>
310 <script type="text/javascript" src="/{{=request.application}}/static/scripts/hs/panels/side_panel.js"></script>
311@@ -62,11 +65,29 @@
312 filename: 'br_pop',
313 type: 'db',
314 },
315+
316+
317 {
318 name: 'Brazil Precipitation',
319 filename: 'br_precip',
320 type: 'db',
321 },
322+
323+ {
324+ name: 'Wher Wildlife Disease',
325+ filename: 'wher',
326+ type: 'db',
327+ },
328+
329+ {
330+ name: 'US States',
331+ filename: 'us_states',
332+ type: 'db',
333+ },
334+
335+
336+
337+
338 ]);
339
340 var tool_list = new hs.side.Tools ({{response.write (tool_list, escape = False)}});
341@@ -110,19 +131,322 @@
342 ],
343 });
344
345+
346+ // Temp Disease Pages START
347+
348+
349+
350+
351+
352+ var nprPanel = new Ext.Panel ({
353+ region: 'west',
354+ title: 'NPR',
355+ autoScroll: true,
356+ width: 400,
357+ padding: 10,
358+ listeners: {
359+ render: function () {
360+ var element = this;
361+ Ext.Ajax.request ({
362+ url: '/{{=request.application}}/sources/npr',
363+ method: 'GET',
364+ params: {
365+ disease: 'Malaria',
366+ },
367+ success: function (data) {
368+ var ob = JSON.parse (data.responseText);
369+ console.log (ob);
370+ var stories = ob.list.story;
371+ console.log (stories);
372+ for (var i = 0; i < stories.length; i ++) {
373+ var html = '<div><a href="' + stories[i].link[2]['$text'] + '">' + stories[i].title['$text'] + '</a><br />' + stories[i].teaser['$text'] + '</div>';
374+ element.add ({
375+ border: false,
376+ padding: 10,
377+ html: html,
378+ });
379+ }
380+ element.doLayout ();
381+ },
382+ failure: function () {
383+ console.log ('NPR API returned error');
384+ },
385+ });
386+ },
387+ },
388+ });
389+
390+
391+ //http://api.npr.org/query?apiKey=MDA2OTc4ODY2MDEyOTc0NTMyMjFmZGNjZg001&searchTerm=malaria
392+
393+ var wikiPanel = new Ext.Panel ({
394+ title: 'Wikipedia',
395+ region: 'center',
396+ autoScroll: true,
397+ padding: 10,
398+ listeners: {
399+ render: function () {
400+ var element = this;
401+ Ext.Ajax.request ({
402+ url: '/{{=request.application}}/sources/wiki',
403+ method: 'GET',
404+ params: {
405+ disease: 'Malaria',
406+ },
407+ success: function (data) {
408+ var ob = data.responseText;
409+ element.add ({
410+ border: false,
411+ html: ob,
412+ });
413+ element.doLayout ();
414+ },
415+ failure: function () {
416+ console.log ('Wiki API returned error');
417+ },
418+ });
419+ },
420+ },
421+ });
422+
423+ var LitPanel = Ext.extend (Ext.Panel, {
424+ constructor: function (config) {
425+ var keywords;
426+ var maps;
427+
428+ var store = new Ext.data.JsonStore ({
429+
430+ });
431+
432+ /*var keyword_root = new Ext.tree.AsyncTreeNode({
433+ expanded: true,
434+ children: childNodes,
435+ });*/
436+
437+ var KeywordRecord = Ext.data.Record.create ([
438+ 'kw',
439+ 'count',
440+ 'numMaps',
441+ 'maps',
442+ ]);
443+
444+ var keywordCols = new Ext.grid.ColumnModel ([
445+ {
446+ id: 'kw',
447+ header: 'Keyword',
448+ sortable: true,
449+ dataIndex: 'kw'
450+ },
451+ {
452+ id: 'count',
453+ header: 'Rank',
454+ sortable: true,
455+ dataIndex: 'count'
456+ },
457+ {
458+ id: 'numMaps',
459+ header: 'Maps',
460+ sortable: true,
461+ dataIndex: 'numMaps'
462+ },
463+ ]);
464+
465+ var mapList = [];
466+
467+ var populate = function () {
468+ Ext.Ajax.request ({
469+ url: '/{{=request.application}}/lit/kw',
470+ method: 'GET',
471+ params: {
472+ d: 'malaria',
473+ },
474+ success: function (data) {
475+ mapList = [];
476+ var ob = JSON.parse (data.responseText);
477+ records = [];
478+ store.removeAll ();
479+ for (var i = 0; i < ob.length; i ++) {
480+ mapList.push (ob[i]['maps']);
481+ records.push (new KeywordRecord (ob[i]));
482+ }
483+ console.log (ob, mapList);
484+ store.add (records);
485+ keywords.reconfigure (store, keywordCols);
486+ },
487+ failure: function () {
488+ console.log ('Lit call went wrong');
489+ },
490+ });
491+ };
492+
493+ populate ();
494+
495+ var addMapNode = function (ob) {
496+ root.appendChild ({
497+ text: ob.name,
498+ leaf: true,
499+ cls: 'file',
500+ id: ob.id,
501+ });
502+ };
503+
504+ var root = new Ext.tree.AsyncTreeNode({
505+ expanded: true,
506+ children: [],
507+ });
508+
509+ maps = new Ext.tree.TreePanel ({
510+ title: 'Maps',
511+ rootVisible: false,
512+ root: root,
513+ expanded: true,
514+ enableDrag: true,
515+ columnWidth: .75,
516+ dragConfig: {
517+ ddGroup: 'layers',
518+ dragAllowed: true,
519+ dropAllowed: false,
520+ },
521+ });
522+
523+ keywords = new Ext.grid.GridPanel ({
524+ title: 'Keywords',
525+ store: store,
526+ columns: keywordCols,
527+ columnWidth: .25,
528+ autoHeight: true,
529+ listeners: {
530+ celldblclick: function (el, rowIndex, colIndex, event) {
531+ root.removeAll ();
532+ var m = mapList[rowIndex];
533+ for (var i = 0; i < m.length; i ++) {
534+ addMapNode (m[i]);
535+ }
536+ maps.doLayout ();
537+ }
538+ },
539+ });
540+
541+ if (!config)
542+ config = {};
543+
544+ Ext.apply (config, {
545+ title: 'Automated',
546+ layout: 'column',
547+ hideBorders: true,
548+ items: [
549+ keywords,
550+ maps,
551+ ],
552+ });
553+
554+ LitPanel.superclass.constructor.call (this, config);
555+ },
556+ });
557+
558+ var litPanel = new LitPanel ();
559+
560+
561+ var mainPanel = new Ext.Panel ({
562+ title: 'Info',
563+ layout: 'border',
564+ region: 'center',
565+ items: [
566+ wikiPanel,
567+ nprPanel,
568+ ],
569+ });
570+
571+ var tabsPanel = new Ext.TabPanel ({
572+ region: 'center',
573+ activeTab: 0,
574+ items: [
575+ mainPanel,
576+ {
577+ title: 'Tools',
578+ html: 'A simple tab',
579+ },{
580+ title: 'Maps',
581+ html: 'A simple tab'
582+ },{
583+ title: 'Research',
584+ html: 'A simple tab'
585+ },
586+ litPanel,
587+ ]
588+ });
589+
590+ //wrapDateLine: true,
591+ //displayOutsideMaxExtent: true,
592+
593+ map = new OpenLayers.Map("Disease Map");
594+ var base = new OpenLayers.Layer.OSM ();
595+ var overlay = new OpenLayers.Layer.WMS (
596+ "Brazil",
597+ geoserver_url + '/wms',
598+ {
599+ layers: "hsd:brazil",
600+ transparent: true,
601+ format: "image/png",
602+ projection: 'EPSG:9000913',
603+ },
604+ {
605+ isBaseLayer: false,
606+ displayOutsideMaxExtent: true,
607+ }
608+ );
609+ map.addLayer (base);
610+ map.addLayer (overlay);
611+ //map.addLayer(overlay);
612+ //map.zoomTo (7);
613+ //map.setCenter (new OpenLayers.LonLat(13.41,52.52), 7);
614+
615+ var mapPanel = new GeoExt.MapPanel({
616+ height: 300,
617+ region: 'north',
618+ map: map,
619+ title: 'Map',
620+ listeners: {
621+ afterlayout: function () {
622+ var center = new OpenLayers.LonLat (-55.0, -10.0);
623+ var proj4326 = new OpenLayers.Projection('EPSG:4326');
624+ var projection_current = new OpenLayers.Projection('EPSG:900913');
625+ center.transform(proj4326, projection_current);
626+ map.setCenter (center, 4);
627+
628+ //map.zoomTo (7);
629+ },
630+ },
631+ });
632+
633+ var diseasePages = new Ext.Panel ({
634+ title: 'Diseases',
635+ region: 'center',
636+ layout: 'border',
637+ items: [
638+ mapPanel,
639+ tabsPanel,
640+ ],
641+ });
642+
643+
644+
645+
646+ // Temp Disease Pages END
647+
648+
649 var tabPanel = new Ext.TabPanel ({
650 activeTab: 0,
651 layoutOnChange: true,
652 region: 'center',
653 items: [
654 mapTab,
655- dataTab,
656+ diseasePages,
657 toolTab,
658 createTab,
659 ],
660 });
661 saved_analyses.setToolPanel (toolTab, tabPanel, 2);
662-
663
664 var win = new Ext.Window({
665 title: 'Healthscapes v0.3',
666@@ -182,6 +506,10 @@
667 },
668 defaultSourceType: 'gx_wmssource',
669 sources: {
670+ local: {
671+ url: geoserver_url + '/wms',
672+ title: 'HS Geoserver',
673+ },
674 {{if geoserver_url:}}
675 local: {
676 url: s3_gis_geoserver_url,
677@@ -225,23 +553,31 @@
678 units: s3_gis_units,
679 maxResolution: s3_gis_maxResolution,
680 maxExtent: s3_gis_maxExtent,
681- layers: [{
682- source: 'osm',
683- name: 'cyclemap',
684- group: 'background'
685- }, {
686- source: 'osm',
687- name: 'mapnik',
688- group: 'background'
689- }, {
690- source: 'ol',
691- group: 'background',
692- fixed: true,
693- type: 'OpenLayers.Layer',
694- args: [
695- 'None', {visibility: false}
696- ]
697- }],
698+ layers: [
699+ {
700+ source: 'osm',
701+ name: 'cyclemap',
702+ group: 'background'
703+ },
704+ {
705+ source: 'osm',
706+ name: 'mapnik',
707+ group: 'background'
708+ },
709+ {
710+ source: 'ol',
711+ group: 'background',
712+ fixed: true,
713+ type: 'OpenLayers.Layer',
714+ args: [
715+ 'None', {visibility: false}
716+ ]
717+ },
718+ /*{
719+ source: 'local',
720+ name: 'topp:states',
721+ },*/
722+ ],
723 center: [s3_gis_center.lon, s3_gis_center.lat],
724 zoom: s3_gis_zoom,
725 numZoomLevels: s3_gis_numZoomLevels
726@@ -274,4 +610,4 @@
727 {{pass}}
728 }, false);
729 </script>
730-
731\ No newline at end of file
732+

Subscribers

People subscribed via source and target branches

to all changes: