fix test with new description field.
[sgn.git] / mason / breeders_toolbox / location_map.mas
blob3ad0856266c2c55493ceae8b8b66dc2139d577c1
2 <%args>
3 $user_id => undef
4 </%args>
6 <& /util/import_javascript.mas, classes => ['leaflet', 'esri-leaflet', 'esri-leaflet-geocoder-debug', 'leaflet_extra-markers_min', 'jquery.dstk'] &>
7 <center><p><i> Add a new location by clicking on the map. Or select an exisiting location to view details and options.</i></p></center>
8 <br>
9 <div id="location_map" style="height: 540px;"></div>
11 <div class="modal fade" id="store_location_dialog" name="store_location_dialog" tabindex="-1" role="dialog" aria-labelledby="storeLocationDialog">
12   <div class="modal-dialog modal-lg" role="document">
13     <div class="modal-content">
14       <div class="modal-header">
15         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
16         <h4 class="modal-title" id="storeLocationDialog">Location Details</h4>
17       </div>
18       <div class="modal-body">
19         <div class="container-fluid">
20           <form class="form-horizontal" role="form" name="store_location_form" id="store_location_form">
21         <div class="form-group" id="location_id" style="display: none"></div>
22             <div class="form-group">
23               <label class="col-sm-2 control-label">Name: </label>
24               <div class="col-sm-10">
25                 <input class="form-control" name="location_name" id="location_name" type="text" />
26               </div>
27             </div>
28         <div class="form-group">
29               <label class="col-sm-2 control-label">Abbreviation: </label>
30               <div class="col-sm-10">
31                 <input class="form-control" name="location_abbreviation" id="location_abbreviation" type="text" />
32               </div>
33             </div>
34         <div class="form-group">
35               <label class="col-sm-2 control-label">Country: </label>
36               <div class="col-sm-10">
37                   <select class="form-control" id="location_country" name="location_country">
38                     <option value=""></option>
39                     <option value="ABW">ABW Aruba </option>
40                     <option value="AFG">AFG Afghanistan </option>
41                     <option value="AGO">AGO Angola </option>
42                     <option value="AIA">AIA Anguilla </option>
43                     <option value="ALA">ALA Åland Islands </option>
44                     <option value="ALB">ALB Albania </option>
45                     <option value="AND">AND Andorra </option>
46                     <option value="ANT">ANT Netherlands Antilles </option>
47                     <option value="ARE">ARE United Arab Emirates </option>
48                     <option value="ARG">ARG Argentina </option>
49                     <option value="ARM">ARM Armenia </option>
50                     <option value="ASM">ASM American Samoa </option>
51                     <option value="ATA">ATA Antarctica </option>
52                     <option value="ATF">ATF French Southern Territories </option>
53                     <option value="ATG">ATG Antigua and Barbuda </option>
54                     <option value="AUS">AUS Australia </option>
55                     <option value="AUT">AUT Austria </option>
56                     <option value="AZE">AZE Azerbaijan </option>
57                     <option value="BDI">BDI Burundi </option>
58                     <option value="BEL">BEL Belgium </option>
59                     <option value="BEN">BEN Benin </option>
60                     <option value="BFA">BFA Burkina Faso </option>
61                     <option value="BGD">BGD Bangladesh </option>
62                     <option value="BGR">BGR Bulgaria </option>
63                     <option value="BHR">BHR Bahrain </option>
64                     <option value="BHS">BHS Bahamas </option>
65                     <option value="BIH">BIH Bosnia and Herzegovina </option>
66                     <option value="BLM">BLM Saint Barthélemy </option>
67                     <option value="BLR">BLR Belarus </option>
68                     <option value="BLZ">BLZ Belize </option>
69                     <option value="BMU">BMU Bermuda </option>
70                     <option value="BOL">BOL Bolivia, Plurinational State of </option>
71                     <option value="BRA">BRA Brazil </option>
72                     <option value="BRB">BRB Barbados </option>
73                     <option value="BRN">BRN Brunei Darussalam </option>
74                     <option value="BTN">BTN Bhutan </option>
75                     <option value="BVT">BVT Bouvet Island </option>
76                     <option value="BWA">BWA Botswana </option>
77                     <option value="CAF">CAF Central African Republic </option>
78                     <option value="CAN">CAN Canada </option>
79                     <option value="CCK">CCK Cocos (Keeling) Islands </option>
80                     <option value="CHE">CHE Switzerland </option>
81                     <option value="CHL">CHL Chile </option>
82                     <option value="CHN">CHN China </option>
83                     <option value="CIV">CIV Côte d'Ivoire </option>
84                     <option value="CMR">CMR Cameroon </option>
85                     <option value="COD">COD Congo, the Democratic Republic of the </option>
86                     <option value="COG">COG Congo </option>
87                     <option value="COK">COK Cook Islands </option>
88                     <option value="COL">COL Colombia </option>
89                     <option value="COM">COM Comoros </option>
90                     <option value="CPV">CPV Cape Verde </option>
91                     <option value="CRI">CRI Costa Rica </option>
92                     <option value="CUB">CUB Cuba </option>
93                     <option value="CXR">CXR Christmas Island </option>
94                     <option value="CYM">CYM Cayman Islands </option>
95                     <option value="CYP">CYP Cyprus </option>
96                     <option value="CZE">CZE Czech Republic </option>
97                     <option value="DEU">DEU Germany </option>
98                     <option value="DJI">DJI Djibouti </option>
99                     <option value="DMA">DMA Dominica </option>
100                     <option value="DNK">DNK Denmark </option>
101                     <option value="DOM">DOM Dominican Republic </option>
102                     <option value="DZA">DZA Algeria </option>
103                     <option value="ECU">ECU Ecuador </option>
104                     <option value="EGY">EGY Egypt </option>
105                     <option value="ERI">ERI Eritrea </option>
106                     <option value="ESH">ESH Western Sahara </option>
107                     <option value="ESP">ESP Spain </option>
108                     <option value="EST">EST Estonia </option>
109                     <option value="ETH">ETH Ethiopia </option>
110                     <option value="FIN">FIN Finland </option>
111                     <option value="FJI">FJI Fiji </option>
112                     <option value="FLK">FLK Falkland Islands (Malvinas) </option>
113                     <option value="FRA">FRA France </option>
114                     <option value="FRO">FRO Faroe Islands </option>
115                     <option value="FSM">FSM Micronesia, Federated States of </option>
116                     <option value="GAB">GAB Gabon </option>
117                     <option value="GBR">GBR United Kingdom </option>
118                     <option value="GEO">GEO Georgia </option>
119                     <option value="GGY">GGY Guernsey </option>
120                     <option value="GHA">GHA Ghana </option>
121                     <option value="GIB">GIB Gibraltar </option>
122                     <option value="GIN">GIN Guinea </option>
123                     <option value="GLP">GLP Guadeloupe </option>
124                     <option value="GMB">GMB Gambia </option>
125                     <option value="GNB">GNB Guinea-Bissau </option>
126                     <option value="GNQ">GNQ Equatorial Guinea </option>
127                     <option value="GRC">GRC Greece </option>
128                     <option value="GRD">GRD Grenada </option>
129                     <option value="GRL">GRL Greenland </option>
130                     <option value="GTM">GTM Guatemala </option>
131                     <option value="GUF">GUF French Guiana </option>
132                     <option value="GUM">GUM Guam </option>
133                     <option value="GUY">GUY Guyana </option>
134                     <option value="HKG">HKG Hong Kong </option>
135                     <option value="HMD">HMD Heard Island and McDonald Islands </option>
136                     <option value="HND">HND Honduras </option>
137                     <option value="HRV">HRV Croatia </option>
138                     <option value="HTI">HTI Haiti </option>
139                     <option value="HUN">HUN Hungary </option>
140                     <option value="IDN">IDN Indonesia </option>
141                     <option value="IMN">IMN Isle of Man </option>
142                     <option value="IND">IND India </option>
143                     <option value="IOT">IOT British Indian Ocean Territory </option>
144                     <option value="IRL">IRL Ireland </option>
145                     <option value="IRN">IRN Iran, Islamic Republic of </option>
146                     <option value="IRQ">IRQ Iraq </option>
147                     <option value="ISL">ISL Iceland </option>
148                     <option value="ISR">ISR Israel </option>
149                     <option value="ITA">ITA Italy </option>
150                     <option value="JAM">JAM Jamaica </option>
151                     <option value="JEY">JEY Jersey </option>
152                     <option value="JOR">JOR Jordan </option>
153                     <option value="JPN">JPN Japan </option>
154                     <option value="KAZ">KAZ Kazakhstan </option>
155                     <option value="KEN">KEN Kenya </option>
156                     <option value="KGZ">KGZ Kyrgyzstan </option>
157                     <option value="KHM">KHM Cambodia </option>
158                     <option value="KIR">KIR Kiribati </option>
159                     <option value="KNA">KNA Saint Kitts and Nevis </option>
160                     <option value="KOR">KOR Korea, Republic of </option>
161                     <option value="KWT">KWT Kuwait </option>
162                     <option value="LAO">LAO Lao People's Democratic Republic </option>
163                     <option value="LBN">LBN Lebanon </option>
164                     <option value="LBR">LBR Liberia </option>
165                     <option value="LBY">LBY Libyan Arab Jamahiriya </option>
166                     <option value="LCA">LCA Saint Lucia </option>
167                     <option value="LIE">LIE Liechtenstein </option>
168                     <option value="LKA">LKA Sri Lanka </option>
169                     <option value="LSO">LSO Lesotho </option>
170                     <option value="LTU">LTU Lithuania </option>
171                     <option value="LUX">LUX Luxembourg </option>
172                     <option value="LVA">LVA Latvia </option>
173                     <option value="MAC">MAC Macao </option>
174                     <option value="MAF">MAF Saint Martin (French part) </option>
175                     <option value="MAR">MAR Morocco </option>
176                     <option value="MCO">MCO Monaco </option>
177                     <option value="MDA">MDA Moldova, Republic of </option>
178                     <option value="MDG">MDG Madagascar </option>
179                     <option value="MDV">MDV Maldives </option>
180                     <option value="MEX">MEX Mexico </option>
181                     <option value="MHL">MHL Marshall Islands </option>
182                     <option value="MKD">MKD Macedonia, the former Yugoslav Republic of </option>
183                     <option value="MLI">MLI Mali </option>
184                     <option value="MLT">MLT Malta </option>
185                     <option value="MMR">MMR Myanmar </option>
186                     <option value="MNE">MNE Montenegro </option>
187                     <option value="MNG">MNG Mongolia </option>
188                     <option value="MNP">MNP Northern Mariana Islands </option>
189                     <option value="MOZ">MOZ Mozambique </option>
190                     <option value="MRT">MRT Mauritania </option>
191                     <option value="MSR">MSR Montserrat </option>
192                     <option value="MTQ">MTQ Martinique </option>
193                     <option value="MUS">MUS Mauritius </option>
194                     <option value="MWI">MWI Malawi </option>
195                     <option value="MYS">MYS Malaysia </option>
196                     <option value="MYT">MYT Mayotte </option>
197                     <option value="NAM">NAM Namibia </option>
198                     <option value="NCL">NCL New Caledonia </option>
199                     <option value="NER">NER Niger </option>
200                     <option value="NFK">NFK Norfolk Island </option>
201                     <option value="NGA">NGA Nigeria </option>
202                     <option value="NIC">NIC Nicaragua </option>
203                     <option value="NIU">NIU Niue </option>
204                     <option value="NLD">NLD Netherlands </option>
205                     <option value="NOR">NOR Norway </option>
206                     <option value="NPL">NPL Nepal </option>
207                     <option value="NRU">NRU Nauru </option>
208                     <option value="NZL">NZL New Zealand </option>
209                     <option value="OMN">OMN Oman </option>
210                     <option value="PAK">PAK Pakistan </option>
211                     <option value="PAN">PAN Panama </option>
212                     <option value="PCN">PCN Pitcairn </option>
213                     <option value="PER">PER Peru </option>
214                     <option value="PHL">PHL Philippines </option>
215                     <option value="PLW">PLW Palau </option>
216                     <option value="PNG">PNG Papua New Guinea </option>
217                     <option value="POL">POL Poland </option>
218                     <option value="PRI">PRI Puerto Rico </option>
219                     <option value="PRK">PRK Korea, Democratic People's Republic of </option>
220                     <option value="PRT">PRT Portugal </option>
221                     <option value="PRY">PRY Paraguay </option>
222                     <option value="PSE">PSE Palestinian Territory, Occupied </option>
223                     <option value="PYF">PYF French Polynesia </option>
224                     <option value="QAT">QAT Qatar </option>
225                     <option value="REU">REU Réunion </option>
226                     <option value="ROU">ROU Romania </option>
227                     <option value="RUS">RUS Russian Federation </option>
228                     <option value="RWA">RWA Rwanda </option>
229                     <option value="SAU">SAU Saudi Arabia </option>
230                     <option value="SDN">SDN Sudan </option>
231                     <option value="SEN">SEN Senegal </option>
232                     <option value="SGP">SGP Singapore </option>
233                     <option value="SGS">SGS South Georgia and the South Sandwich Islands </option>
234                     <option value="SHN">SHN Saint Helena, Ascension and Tristan da Cunha </option>
235                     <option value="SJM">SJM Svalbard and Jan Mayen </option>
236                     <option value="SLB">SLB Solomon Islands </option>
237                     <option value="SLE">SLE Sierra Leone </option>
238                     <option value="SLV">SLV El Salvador </option>
239                     <option value="SMR">SMR San Marino </option>
240                     <option value="SOM">SOM Somalia </option>
241                     <option value="SPM">SPM Saint Pierre and Miquelon </option>
242                     <option value="SRB">SRB Serbia </option>
243                     <option value="STP">STP Sao Tome and Principe </option>
244                     <option value="SUR">SUR Suriname </option>
245                     <option value="SVK">SVK Slovakia </option>
246                     <option value="SVN">SVN Slovenia </option>
247                     <option value="SWE">SWE Sweden </option>
248                     <option value="SWZ">SWZ Swaziland </option>
249                     <option value="SYC">SYC Seychelles </option>
250                     <option value="SYR">SYR Syrian Arab Republic </option>
251                     <option value="TCA">TCA Turks and Caicos Islands </option>
252                     <option value="TCD">TCD Chad </option>
253                     <option value="TGO">TGO Togo </option>
254                     <option value="THA">THA Thailand </option>
255                     <option value="TJK">TJK Tajikistan </option>
256                     <option value="TKL">TKL Tokelau </option>
257                     <option value="TKM">TKM Turkmenistan </option>
258                     <option value="TLS">TLS Timor-Leste </option>
259                     <option value="TON">TON Tonga </option>
260                     <option value="TTO">TTO Trinidad and Tobago </option>
261                     <option value="TUN">TUN Tunisia </option>
262                     <option value="TUR">TUR Turkey </option>
263                     <option value="TUV">TUV Tuvalu </option>
264                     <option value="TWN">TWN Taiwan, Republic of China </option>
265                     <option value="TZA">TZA Tanzania, United Republic of </option>
266                     <option value="UGA">UGA Uganda </option>
267                     <option value="UKR">UKR Ukraine </option>
268                     <option value="UMI">UMI United States Minor Outlying Islands </option>
269                     <option value="URY">URY Uruguay </option>
270                     <option value="USA">USA United States </option>
271                     <option value="UZB">UZB Uzbekistan </option>
272                     <option value="VAT">VAT Holy See (Vatican City State) </option>
273                     <option value="VCT">VCT Saint Vincent and the Grenadines </option>
274                     <option value="VEN">VEN Venezuela, Bolivarian Republic of </option>
275                     <option value="VGB">VGB Virgin Islands, British </option>
276                     <option value="VIR">VIR Virgin Islands, U.S. </option>
277                     <option value="VNM">VNM Viet Nam </option>
278                     <option value="VUT">VUT Vanuatu </option>
279                     <option value="WLF">WLF Wallis and Futuna </option>
280                     <option value="WSM">WSM Samoa </option>
281                     <option value="YEM">YEM Yemen </option>
282                     <option value="ZAF">ZAF South Africa </option>
283                     <option value="ZMB">ZMB Zambia </option>
284                     <option value="ZWE">ZWE Zimbabwe</option>
285                   </select>
286               </div>
287             </div>
288         <div class="form-group">
289               <label class="col-sm-2 control-label">Program: (One or More)</label>
290               <div class="col-sm-10" id="breeding_program" name="breeding_program">
291               </div>
292             </div>
293         <div class="form-group">
294               <label class="col-sm-2 control-label">Type: </label>
295               <div class="col-sm-10">
296                   <select class="form-control" id="location_type" name="location_type">
297                       <option value=""></option>
298                       <option value="Town">Town</option>
299                       <option value="Farm">Farm</option>
300                       <option value="Field">Field</option>
301                       <option value="Greenhouse">Greenhouse</option>
302                       <option value="Screenhouse">Screenhouse</option>
303                       <option value="Lab">Lab</option>
304                       <option value="Storage">Storage</option>
305                       <option value="Other">Other</option>
306                   </select>
307               </div>
308         </div>
309         <div class="form-group">
310             <label class="col-sm-2 control-label">Latitude: </label>
311             <div class="col-sm-10">
312                 <input class="form-control" name="location_latitude" id="location_latitude" type="text" size="4"/>
313             </div>
314         </div>
315         <div class="form-group">
316             <label class="col-sm-2 control-label">Longitude: </label>
317             <div class="col-sm-10">
318                 <input class="form-control" name="location_longitude" id="location_longitude" type="text" size="4"/>
319             </div>
320         </div>
321         <div class="form-group">
322             <label class="col-sm-2 control-label">Altitude (m): </label>
323             <div class="col-sm-10">
324                 <input class="form-control" name="location_altitude" id="location_altitude" type="text" size="4"/>
325             </div>
326         </div>
327         <div class="form-group">
328             <label class="col-sm-6 control-label"><i>Optional:</i> Nearest NOAA Weather Station ID (<a href="https://www.ncdc.noaa.gov/cdo-web/datatools/findstation" target="_blank">Search Here</a>)</label>
329             <div class="col-sm-6">
330                 <input class="form-control" name="location_noaa_station_id" id="location_noaa_station_id" type="text" placeholder="e.g. GHCND:USC00300331"/>
331             </div>
332         </div>
333           </form>
334         </div>
335       </div>
336       <div class="modal-footer">
337         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
338         <button type="button" class="btn btn-primary" name="store_location_submit" id="store_location_submit">Store Location Details</button>
339       </div>
340     </div>
341   </div>
342 </div>
344 <script defer="defer">
346 jQuery(document).ready(function() {
348   $('#add_location_link').click( function() {
349       $('#add_location_dialog').modal("show");
350    });
352    // get_select_box("breeding_programs", "breeding_program", {'empty':1, 'default':'please select'});
353    get_select_box('breeding_programs', 'breeding_program',
354        {
355            empty: 1,
356            id: 'breeding_program_select',
357            default: 'please select',
358            multiple: 1,
359        });
361    $('#store_location_submit').click( function(event) {
362        event.preventDefault();
363        var id= $('#location_id').val();
364        var name = $('#location_name').val();
365        name = name.trim();
366        var abbreviation = $('#location_abbreviation').val();
367        var country_code = $('#location_country').val();
368        var country_text = $('#location_country option:selected').text();
369        var country_name = country_text.replace(/^[^\s]+(.*)/, '$1').trim();
370         var programs = [];
371         $('#breeding_program_select option:selected').each( function() {
372             programs.push($(this).text());
373         });
375         var noaa_station_id = $('#location_noaa_station_id').val();
377         programs = programs.join("&");
378         var type = $('#location_type').val();
379         var latitude = $('#location_latitude').val();
380         var longitude = $('#location_longitude').val();
381         var altitude = $('#location_altitude').val();
382         //console.log("Location programs to store are "+JSON.stringify(programs));
383         //console.log("Location name to store is "+name);
384         //console.log("Location country name to store is "+country_name+" and country code is "+country_code);
386         if (name == '') { alert('A location name is required.');  return; }
387         if (abbreviation == '') { alert('A location abbreviation is required.');  return; }
388         if ($('#location_country').val() == '') { alert('A location country is required.');  return; }
389         if (type == '') { alert('A location type is required.');  return; }
390         if (latitude == '') { alert('A location latitude is required.');  return; }
391         if (longitude == '') { alert('A location longitude is required.');  return; }
392         if (altitude == '') { alert('A location altitude is required.');  return; }
394         $.ajax({
395             type: 'POST',
396             url: '/ajax/location/store',
397             data: {
398                 'id': id,
399                 'name': name,
400                 'abbreviation': abbreviation,
401                 'country_name': country_name,
402                 'country_code': country_code,
403                 'programs': programs,
404                 'type': type,
405                 'latitude':latitude,
406                 'longitude':longitude,
407                 'altitude': altitude,
408                 'noaa_station_id': noaa_station_id
409             },
410             success: function(response) {
411                 if (response.error) { alert(response.error); }
412                 else {
413                     var token = '<% $c->config->{noaa_ncdc_access_token} %>';
414                     if (noaa_station_id == '') {
415                       // do nothing
416                     } else if (token == 'NULL') {
417                       alert(`Configuration variable 'noaa_ncdc_access_token' is undefined. Data from station `+noaa_station_id+` can't be accessed without a token.\r\nPlease visit https://www.ncdc.noaa.gov/cdo-web/token to generate a valid access token, then include the token in sgn_local.conf`);
418                     } else {
419                         $.ajax({
420                             url:'https://www.ncdc.noaa.gov/cdo-web/api/v2/stations/'+noaa_station_id,
421                             headers:{ token: token },
422                             success: function(response) {
423                                 console.log(response);
424                                 if (response.name) {
425                                     alert('Found NOAA Station from given NOAA StationID: '+response.name);
426                                 }
427                                 else {
428                                     alert('Could not verify the NOAA StationID you provided, however, your details were still updated.');
429                                 }
430                                 $('#store_location_dialog').modal("hide");
431                                 location.reload();
432                             },
433                             error: function() {
434                                 alert('The NOAA NCDC authorization token may not be valid! We could not verify your NOAA StationID. Please contact us!');
435                             }
436                         });
437                     }
438                     alert(response.success);
439                 }
440             },
441             error: function() { alert('An error occurred while storing the location details. Please try again later.'); }
442         });
443    });
446 function initialize_map (id, locationJSON, table) {
448     var satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
449            attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
450     });
452     var topomap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
453         attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
454     });
456     var streetmap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
457         attribution: 'Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
458     });
460     var baseMaps = {
461         "Street (Default)": streetmap,
462         "Topographical": topomap,
463         "Satellite": satellite
464     };
466     var location_layer = L.geoJSON(locationJSON, {
467         pointToLayer: function (feature, latlng) {
468            return L.marker(latlng, style(feature));
469        },
470        onEachFeature: onEachFeature
471     });
473     var overlayMaps = {
474         "Locations": location_layer
475     };
477     var mymap = L.map( id, {
478         layers: [streetmap, location_layer]
479     });
481     var locateUser = L.Control.extend({
482         onAdd: function (map) {
483             var container = L.DomUtil.create('button', 'leaflet-bar leaflet-control leaflet-control-custom glyphicon glyphicon-map-marker');
485             container.style.backgroundColor = 'white';
486             container.style.cursor = "pointer";
487             container.title = 'Zoom to my location';
488             container.style.width = '30px';
489             container.style.height = '30px';
491             container.onclick = function(){
492               map.locate({setView: true});
493             }
494             return container;
495         }
496     });
498     mymap.addControl(new locateUser({ position: 'topleft' }));
500     // Set Map Bounds if provided, otherwise fit the map to the world
501     if ( Object.entries(location_layer.getBounds()).length !== 0 ) {
502         mymap.fitBounds(location_layer.getBounds());
503     }
504     else {
505         mymap.fitWorld();
506     }
507     var layerControl = L.control.layers(baseMaps, overlayMaps, {position: 'bottomright'}).addTo(mymap);
508     var scale = L.control.scale().addTo(mymap);
510     var popup = L.popup();
512     function onMapClick(e) {
513         popup
514             .setLatLng(e.latlng)
515             .setContent(
516                 'Add a new location here?<br><center><a href="javascript:;" onclick="add_from_map(\''+e.latlng.lat+','+e.latlng.lng+'\')">Add Location</a></center>'
517             )
518             .openOn(mymap);
519     }
521     mymap.on('click', onMapClick);
523     var arcgisOnline = L.esri.Geocoding.arcgisOnlineProvider();
525     var searchControl = L.esri.Geocoding.geosearch({
526         providers: [
527           arcgisOnline,
528           L.esri.Geocoding.featureLayerProvider({
529             url: 'https://services.arcgis.com/uCXeTVveQzP4IIcx/arcgis/rest/services/gisday/FeatureServer/0/',
530             searchFields: ['Name', 'Organization'],
531             label: 'GIS Day Events',
532             bufferRadius: 5000,
533             formatSuggestion: function(feature){
534               return feature.properties.Name + ' - ' + feature.properties.Organization;
535             }
536           })
537       ],
538       position: 'topright',
539       expanded: true
540     }).addTo(mymap);
542     table.on( 'draw.dt', function () {  // recreate location layer based on filtered table contents
543         location_layer.clearLayers();
544         var ids = {};
545         table.column(0,  { search:'applied' } ).data().each(function(value, index) {
546             ids[value] = true;
547         });
548         layerControl.removeLayer(location_layer);
549         location_layer = L.geoJson(locationJSON, {
550             filter: function(feature, layer) {
551                 return ids[feature.properties.Id];
552             },
553             pointToLayer: function (feature, latlng) {
554                return L.marker(latlng, style(feature));
555            },
556            onEachFeature: onEachFeature
557         });
559         layerControl.addOverlay(location_layer, "Locations");
560         location_layer.addTo(mymap);
561         mymap.fitBounds(location_layer.getBounds());
562     });
563     return;
566 function style(feature) {
567     //console.log("Type of marker "+feature.properties.Name+" is "+feature.properties.Type);
569     var label = feature.properties.Abbreviation || feature.properties.Id;
571     var townMarker = L.ExtraMarkers.icon({
572         icon: 'fa-number',
573         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
574         markerColor: 'purple',
575         shape: 'circle',
576         prefix: ''
577     });
579     var farmMarker = L.ExtraMarkers.icon({
580         icon: 'fa-number',
581         // number: feature.properties.Id,
582         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
583         markerColor: 'red',
584         shape: 'circle',
585         prefix: ''
586     });
588     var fieldMarker = L.ExtraMarkers.icon({
589         icon: 'fa-number',
590         // number: feature.properties.Id,
591         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
592         markerColor: 'orange',
593         shape: 'circle',
594         prefix: ''
595     });
597     var defaultMarker = L.ExtraMarkers.icon({
598         icon: 'fa-number',
599         // number: feature.properties.Id,
600         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
601         markerColor: 'cyan',
602         shape: 'circle',
603         prefix: ''
604     });
606     var greenhouseMarker = L.ExtraMarkers.icon({
607         icon: 'fa-number',
608         // number: feature.properties.Id,
609         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
610         markerColor: 'green-light',
611         shape: 'penta',
612         prefix: ''
613     });
615     var screenhouseMarker = L.ExtraMarkers.icon({
616         icon: 'fa-number',
617         // number: feature.properties.Id,
618         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
619         markerColor: 'white',
620         shape: 'penta',
621         prefix: ''
622     });
624     var labMarker = L.ExtraMarkers.icon({
625         icon: 'fa-number',
626         // number: feature.properties.Id,
627         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
628         markerColor: 'blue',
629         shape: 'square',
630         prefix: ''
631     });
633     var storageMarker = L.ExtraMarkers.icon({
634         icon: 'fa-number',
635         // number: feature.properties.Id,
636         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
637         markerColor: 'purple',
638         shape: 'square',
639         prefix: ''
640     });
642     var otherMarker = L.ExtraMarkers.icon({
643         icon: 'fa-number',
644         // number: feature.properties.Id,
645         innerHTML: '<div style="color: white; position: relative; top: 50%; transform: translateY(-50%); font-size: 80%">'+label+'</div>',
646         markerColor: 'pink',
647         shape: 'circle',
648         prefix: ''
649     });
651     switch (feature.properties.Type) {
652         case 'Town':   return { icon: townMarker };
653         case 'Farm':   return { icon: farmMarker };
654         case 'Field': return { icon: fieldMarker };
655         case 'Greenhouse':   return { icon: greenhouseMarker };
656         case 'Screenhouse':   return { icon: screenhouseMarker };
657         case 'Lab':   return { icon: labMarker };
658         case 'Storage':   return { icon: storageMarker };
659         case 'Other':   return { icon: otherMarker };
660         default:    return { icon: defaultMarker };
661     }
664 function onEachFeature(feature, layer) {
665         // var keys = ["Id","Name","Abbreviation","Country","Program","Type","Latitude","Longitude","Altitude","Trials"];
666         var keys = ["Abbreviation","Program","Type","Trials"];
667         var popupContent = '<table class="table table-sm"><caption style="text-align: center;"><font id="'+feature.properties.Id+'_name" size="3" color="black">'+feature.properties.Name+'</font></caption><tbody>';
668         for (var i = 0; i < keys.length; i++) {
669             popupContent += '<tr><th>'+keys[i]+'</th><td>'+feature.properties[keys[i]]+'</td></tr>';
670         }
671         var options = '[<a href="javascript:;" onclick="edit_location('+feature.properties.Id+')">Edit</a>]&nbsp[<a href="javascript:;" onclick="delete_location('+feature.properties.Id+')">Delete</a>]';
672         popupContent += '<tr><th>Options</th><td>'+options+'</td></tr></tbody></table>';
673         layer.bindPopup(popupContent);
674         layer.on('mouseover', function (e) {
675             this.openPopup();
676         });
679   function delete_location(id) {
680     var name = $('#'+id+'_name').text();
681     var yes = confirm('Are you sure you want to delete location '+name+'? ');
683     if (! yes) { return; }
685     new jQuery.ajax( {
686       type: 'POST',
687       url: '/ajax/location/delete/'+id,
688       success: function(response) {
689                   if (response.error) { alert(response.error); }
690                   else {
691                     alert(response.success);
692                     location.reload();
693                   }
694                },
695       error: function(response) {
696                  alert("An error occurred");
697              }
698       });
699    }
702     function add_from_map(coordinate_string) {
703         //console.log("coordinate_string is"+coordinate_string);
704         var latlng = coordinate_string.split(',');
705         latitude = latlng[0], longitude = latlng[1];
706         var coordinates = [parseFloat(latitude),parseFloat(longitude)];
709         // removed because of mixed content restrictions. Can be uncommented once datascience toolkit can be accessed locally or over https
711         // var dstk = $.DSTK();
712         // dstk.coordinates2statistics(coordinates, function(c2s_result) {
713         //
714         //   dstk.coordinates2politics(coordinates, function(c2p_result) {
715             //console.log("elevation result is "+JSON.stringify(c2s_result));
716             //console.log("politics result is "+JSON.stringify(c2p_result));
717             //console.log("elevation result is "+c2s_result[0].statistics.elevation+" and politics result is "+c2p_result[0].politics);
718             // if (!c2s_result[0].statistics.elevation || !c2p_result[0].politics) {
719             //     alert("Unable to add a location at these coordinates. Please make sure your new location is located on land between 60 north and south.");
720             //     return;
721             // }
722             // var elevation = c2s_result[0].statistics.elevation.value;
723             // var code= c2p_result[0].politics[0].code.toUpperCase();
724             //console.log("elevation is "+elevation+" and code is "+code);
727             $('#location_id').val('');
728             $('#location_name').val('');
729             $('#location_abbreviation').val('');
730             $('#breeding_program_select').val('');
731             $('#location_type').val('');
732             // $('#location_country').val(code);
733             // $('#location_altitude').val(elevation);
734             $('#location_country').val('');
735             $('#location_altitude').val('');
736             $('#location_latitude').val(coordinates[0]);
737             $('#location_longitude').val(coordinates[1]);
738             $('#store_location_dialog').modal("show");
739         //   });
740         // });
742     }
744    function edit_location(id) {
746         var table = jQuery('#location_table').DataTable();
747         var loc_data = table.row('#'+id).data();
748         //console.log("Data for location to edit: "+JSON.stringify(loc_data));
749         //console.log("Program for location to edit is "+loc_data.properties.Program);
750         $('#location_id').val(loc_data.properties.Id);
751         $('#location_name').val(loc_data.properties.Name);
752         $('#location_abbreviation').val(loc_data.properties.Abbreviation);
753         $('#location_country').val(loc_data.properties.Code);
755         $('#breeding_program_select option:selected').prop('selected', false);
757         var programs = loc_data.properties.Program;
758         var program_array = [];
759         if (programs) { program_array = programs.split(" & ") };
761         if (program_array.length > 0) {
762             program_array.forEach(function(program) {
763                 $("#breeding_program_select option").filter(function() {
764                     return this.text == program
765                 }).attr('selected', true);
766             });
767         } else {
768             $('#breeding_program_select option:first').text('');
769             $('#breeding_program_select option:first').prop('selected', true);
770         }
772         $('#location_type').val(loc_data.properties.Type);
773         $('#location_latitude').val(loc_data.properties.Latitude);
774         $('#location_longitude').val(loc_data.properties.Longitude);
775         $('#location_altitude').val(loc_data.properties.Altitude);
776         $('#location_noaa_station_id').val(loc_data.properties.NOAAStationID);
777         $('#store_location_dialog').modal("show");
778     }
780 </script>