1
+ <!DOCTYPE html>
2
+ < html >
3
+ < head >
4
+ < meta charset ="utf-8 " />
5
+ < meta http-equiv ="X-UA-Compatible " content ="IE=edge ">
6
+ < title > Page Title</ title >
7
+ < meta name ="viewport " content ="width=device-width, initial-scale=1 ">
8
+
9
+ <!-- TODO download this css (Issue 1) -->
10
+ < link rel ="stylesheet " href ="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css ">
11
+ < link rel ="stylesheet " href ="./src/css/sunburst.css ">
12
+ </ head >
13
+
14
+ < body >
15
+ < div class ="content ">
16
+ < div id ="breadcrumbs " class ="crumbs breadcrumb ">
17
+ < span class ="crumb "> </ span >
18
+ </ div >
19
+ < div id ="container-chart " class ="container-chart ">
20
+ < div id ="chart " class ="chart "> </ div >
21
+ </ div >
22
+ < div >
23
+ < div class ="container-map ">
24
+ < div id ="map-loader ">
25
+ < div class ="loader "> </ div >
26
+ </ div >
27
+ < div id ="map " class ="map ">
28
+ < div class ="advanced-button-control ">
29
+ < a id ="advanced-button " class ="advanced-button button " target ="_blank "> </ a >
30
+ </ div >
31
+ </ div >
32
+ < div id ="container-description " class ="container-description ">
33
+ < div id ="description-loader ">
34
+ < div class ="loader2 "> </ div >
35
+ </ div >
36
+ < div class ="row ">
37
+ < div class ="col ">
38
+ < div class ="container-description-row ">
39
+ < label id ="container-title-row-content "> </ label >
40
+ </ div >
41
+ </ div >
42
+ </ div >
43
+ < div class ="row ">
44
+ < div class ="col ">
45
+ < div class ="container-description-row ">
46
+ < div id ="container-description-row-content " class ="container-description-row-content "> </ div >
47
+ </ div >
48
+ </ div >
49
+ </ div >
50
+ </ div >
51
+ < div id ="container-legend " class ="container-legend ">
52
+ < div id ="legend-loader ">
53
+ < div class ="loader2 "> </ div >
54
+ </ div >
55
+ < label > Legenda </ label >
56
+ < img id ="legend-image ">
57
+ </ div >
58
+ </ div >
59
+ </ div >
60
+ </ div >
61
+ < div id ="footer " class ="footer ">
62
+ < div id ="img1 " class ="footer-image1 ">
63
+ < img class ="footer-images " src ="./src/images/portal.svg " alt ="">
64
+ </ div >
65
+ < div id ="img2 " class ="footer-image2 ">
66
+ < img class ="footer-images " src ="./src/images/insa.svg " alt ="">
67
+ </ div >
68
+ </ div >
69
+
70
+ <!-- TODO download this scripts (Issue 1) -->
71
+ < script src ="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL "> </ script >
72
+ < script src ="https://code.jquery.com/jquery-3.3.1.min.js "> </ script >
73
+ < script src ="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js "> </ script >
74
+ < script src ="./src/js/sunburst-chat-ed.js "> </ script >
75
+ < script src ="./src/js/data/desertificacao-data.js "> </ script >
76
+ < script src ="//d3js.org/d3.v5.min.js "> </ script >
77
+
78
+ < link href ="./src/css/ol-geocoder-ed.css " rel ="stylesheet ">
79
+ < script src ="https://cdn.jsdelivr.net/npm/ol-geocoder "> </ script >
80
+
81
+ < script type ="text/javascript ">
82
+ const GEONODE_URL = 'http://sades.insa.gov.br' ;
83
+ const GEOSERVER_URL = 'http://sades.insa.gov.br/geoserver/ows/' ;
84
+ const DEFAULT_LAYER_OPACITY = 0.85 ;
85
+ changeAdvancedButton = ( imgName ) => {
86
+ let url = GEONODE_URL + '/maps/new?layer=' + imgName ;
87
+ $ ( '#advanced-button' ) . attr ( "href" , url ) ;
88
+ }
89
+ fillLegend = ( imgName ) => {
90
+ let legendContainerElement = $ ( '#container-legend' )
91
+
92
+ if ( imgName == null || imgName === '' ) {
93
+ legendContainerElement . hide ( ) ;
94
+ return ;
95
+ } else {
96
+ legendContainerElement . show ( ) ;
97
+ }
98
+ const urlSufix = '?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=' + imgName ;
99
+ // show loader
100
+ let legendLoadingElement = $ ( '#legend-loader' ) ;
101
+ legendLoadingElement . show ( ) ;
102
+
103
+ const url = GEOSERVER_URL + urlSufix ;
104
+ let legendElement = $ ( '#legend-image' ) ;
105
+ legendElement . attr ( "src" , url ) ;
106
+ legendElement . on ( "load" , ( ) => {
107
+ // hidden loader
108
+ legendLoadingElement . hide ( ) ;
109
+ } ) ;
110
+ legendElement . on ( "error" , ( ) => {
111
+ // hidden loader
112
+ legendLoadingElement . hide ( ) ;
113
+ } ) ;
114
+ }
115
+ fillBreadcrumbs = ( data ) => {
116
+ let breadcrumbsArr = getNameArray ( data . __dataNode , [ ] ) ;
117
+ let breadcrumbs_container = $ ( "#breadcrumbs" ) ;
118
+
119
+ breadcrumbs_container . empty ( ) ;
120
+ breadcrumbsArr . reverse ( ) . forEach ( ( value ) => {
121
+ breadcrumbs_container . append ( '<span class="crumb">' + value + '</span>' ) ;
122
+ } ) ;
123
+ }
124
+ getNameArray = ( data , array ) => {
125
+ array = array || [ ] ;
126
+ array . push ( data . data . name2 ) ;
127
+ if ( data . parent ) getNameArray ( data . parent , array ) ;
128
+ return array ;
129
+ } ;
130
+ fillDescrition = ( data ) => {
131
+ let titleContentEl = '#container-title-row-content' ;
132
+ let descriptionContentEl = '#container-description-row-content' ;
133
+ $ ( titleContentEl ) . text ( data . name2 ? data . name2 : '-' ) ;
134
+ $ ( descriptionContentEl ) . text ( '' ) ;
135
+ let descriptionLoaderElement = $ ( '#description-loader' ) ;
136
+ descriptionLoaderElement . show ( ) ;
137
+ let url = GEONODE_URL + '/layers/' + data . imgName + '/metadata_detail_rest' ;
138
+ $ . get ( url )
139
+ . done ( function ( data ) {
140
+ $ ( titleContentEl ) . text ( data . title ) ;
141
+ $ ( descriptionContentEl ) . text ( data . abstract ) ;
142
+ } )
143
+ . fail ( function ( error ) {
144
+ $ ( titleContentEl ) . text ( data . name2 ? data . name2 : '-' ) ;
145
+ $ ( descriptionContentEl ) . text ( '' ) ;
146
+ } )
147
+ . always ( function ( ) {
148
+ descriptionLoaderElement . hide ( ) ;
149
+ } ) ;
150
+ } ;
151
+ // TODO check. This "Loading" management might become a new js file
152
+ let layersLoadingCount = 0 ;
153
+ tryStartLoading = ( ) => {
154
+ if ( layersLoadingCount <= 0 ) {
155
+ $ ( '#map-loader' ) . show ( ) ;
156
+ }
157
+ layersLoadingCount ++ ;
158
+ }
159
+ tryEndLoading = ( ) => {
160
+ layersLoadingCount > 0 && layersLoadingCount -- ;
161
+ if ( layersLoadingCount == 0 ) {
162
+ $ ( '#map-loader' ) . hide ( ) ;
163
+ }
164
+ }
165
+ tryForceEndLoading = ( ) => {
166
+ $ ( '#map-loader' ) . hide ( ) ;
167
+ layersLoadingCount = 0 ;
168
+ }
169
+
170
+ let currentLayer ;
171
+ createLayer = ( imgName ) => {
172
+ currentLayer = imgName ;
173
+ layer = new ol . layer . Tile ( {
174
+ opacity : DEFAULT_LAYER_OPACITY ,
175
+ visible : true ,
176
+ source : new ol . source . TileWMS ( {
177
+ url : GEOSERVER_URL ,
178
+ params : {
179
+ 'LAYERS' : imgName ,
180
+ 'TILED' : 'true'
181
+ } ,
182
+ ratio : 3 ,
183
+ serverType : "geoserver"
184
+ } )
185
+ } ) ;
186
+ tryForceEndLoading ( ) ;
187
+ layer . getSource ( ) . on ( 'tileloadstart' , function ( event ) {
188
+ tryStartLoading ( ) ;
189
+ } ) ;
190
+ layer . getSource ( ) . on ( 'tileloadend' , function ( event ) {
191
+ tryEndLoading ( ) ;
192
+ } ) ;
193
+ layer . getSource ( ) . on ( 'tileloaderror' , function ( event ) {
194
+ tryEndLoading ( ) ;
195
+ } ) ;
196
+ return layer ;
197
+ }
198
+ calculateChartSize = ( ) => {
199
+ const DEFAULT_PERCENT_SIZE = 0.9 ;
200
+ const DEFAULT_SIZE = 400 ;
201
+ try {
202
+ return parseInt ( $ ( "#container-chart" ) . css ( 'width' ) ) * DEFAULT_PERCENT_SIZE ;
203
+ } catch ( error ) {
204
+ return DEFAULT_SIZE ;
205
+ }
206
+ } ;
207
+ stopPeddingRequests = ( ) => {
208
+ window . stop ( ) ;
209
+ }
210
+ let sunburst ;
211
+ $ ( document ) . ready ( ( ) => {
212
+ let defaultL = new ol . layer . Tile ( {
213
+ source : new ol . source . OSM ( )
214
+ } ) ;
215
+ const initialImgNameLayer = dataDesertificacao . imgName ;
216
+ let rootLayer = createLayer ( initialImgNameLayer ) ;
217
+ // TODO (refactoring) put the center parameters in a constant (Issue 4)
218
+ let map = new ol . Map ( {
219
+ layers : [ defaultL , rootLayer ] ,
220
+ target : "map" ,
221
+ view : new ol . View ( {
222
+ center : [ - 4615573.515972 , - 794945.094166 ] ,
223
+ zoom : 5
224
+ } )
225
+ } ) ;
226
+ let geocoder = new Geocoder ( 'nominatim' , {
227
+ provider : 'osm' ,
228
+ lang : 'pt-BR' ,
229
+ placeholder : 'Pesquisa por município . . .' ,
230
+ targetType : 'glass-button' ,
231
+ limit : 2 ,
232
+ keepOpen : true
233
+ } ) ;
234
+ geocoder . on ( 'addresschosen' , function ( evt ) {
235
+ map . getView ( ) . animate ( { zoom : 10 , center : evt . coordinate } ) ;
236
+ // TODO study who the geocode works
237
+ // to colapse the search field
238
+ $ ( "#map" ) . click ( ) ;
239
+ } ) ;
240
+ map . addControl ( geocoder ) ;
241
+ // TODO analyze this approach, because only works in the page initialization (Issue 5)
242
+ let chartContainerSize = calculateChartSize ( ) ;
243
+ let color = d3 . scaleOrdinal ( d3 . schemePaired ) ;
244
+ // TODO (refactoring) put the "data" in another file. (Issue 6)
245
+ const DATA_DESERT_ATTR_LABEL = "name2" ;
246
+ const DATA_DESERT_ATTR_SIZE = "size" ;
247
+ sunburst = Sunburst ( )
248
+ . data ( dataDesertificacao )
249
+ . label ( DATA_DESERT_ATTR_LABEL )
250
+ . size ( DATA_DESERT_ATTR_SIZE )
251
+ . width ( chartContainerSize )
252
+ . height ( chartContainerSize )
253
+ . color ( ( d , parent ) => d . color ) ;
254
+ sunburst . onNodeClick ( choosenData => {
255
+ let imgName = choosenData . imgName ;
256
+ if ( currentLayer === imgName ) {
257
+ console . log ( 'The same image. Do nothing.' )
258
+ return ;
259
+ }
260
+ stopPeddingRequests ( ) ;
261
+ map . getLayers ( ) . clear ( ) ;
262
+ sunburst . focusOnNode ( choosenData ) ;
263
+
264
+ let layer1 = createLayer ( imgName ) ;
265
+ map . addLayer ( defaultL ) ;
266
+ map . addLayer ( layer1 ) ;
267
+
268
+ changeAdvancedButton ( choosenData . imgName ) ;
269
+ fillBreadcrumbs ( choosenData ) ;
270
+ fillLegend ( choosenData . imgName ) ;
271
+ fillDescrition ( choosenData ) ;
272
+ } ) ;
273
+ sunburst ( $ ( "#chart" ) [ 0 ] ) ;
274
+ changeAdvancedButton ( initialImgNameLayer ) ;
275
+ fillBreadcrumbs ( dataDesertificacao ) ;
276
+ fillLegend ( initialImgNameLayer ) ;
277
+ fillDescrition ( dataDesertificacao ) ;
278
+ } ) ;
279
+ $ ( '#navbar li' ) . on ( "click" , ( ) => {
280
+ stopPeddingRequests ( ) ;
281
+ } ) ;
282
+ let resizing = false ;
283
+ $ ( window ) . on ( 'resize' , function ( ) {
284
+ const RESIZING_TIMEOUT = 1000 ;
285
+ if ( ! resizing ) {
286
+ resizing = true ;
287
+ setTimeout ( ( ) => {
288
+ let chartContainerSize = calculateChartSize ( ) ;
289
+ sunburst . width ( chartContainerSize ) ;
290
+ sunburst . height ( chartContainerSize ) ;
291
+ $ ( "#chart" ) . html ( '' ) ;
292
+ sunburst ( $ ( "#chart" ) [ 0 ] ) ;
293
+ resizing = false ;
294
+ } , RESIZING_TIMEOUT ) ;
295
+ }
296
+ } ) ;
297
+ </ script >
298
+
299
+ </ body >
300
+ </ html >
0 commit comments