diff --git a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java index 9d13ac32d2d5a3794f403847a34548bac5e3eff1..557b06f15341549b911200f6756b5da01f594c2e 100755 --- a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java +++ b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java @@ -50,6 +50,7 @@ public class VIPSLogicApplication extends Application resources.add(no.nibio.vips.logic.modules.barleynetblotch.BarleyNetBlotchModelService.class); resources.add(no.nibio.vips.logic.modules.wheatleafblotch.WheatLeafBlotchModelService.class); resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class); + resources.add(no.nibio.vips.logic.modules.barkbeetle.BarkbeetleService.class); resources.add(no.nibio.vips.observationdata.ObservationDataService.class); resources.add(no.nibio.vips.logic.messaging.sms.SMSHandlingService.class); resources.add(no.nibio.vips.logic.modules.applefruitmoth.AppleFruitMothService.class); @@ -70,6 +71,7 @@ public class VIPSLogicApplication extends Application private void addRestResourceClasses(Set<Class<?>> resources) { resources.add(no.nibio.vips.logic.messaging.sms.SMSHandlingService.class); resources.add(no.nibio.vips.logic.modules.applefruitmoth.AppleFruitMothService.class); + resources.add(no.nibio.vips.logic.modules.barkbeetle.BarkbeetleService.class); resources.add(no.nibio.vips.logic.modules.barleynetblotch.BarleyNetBlotchModelService.class); resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class); resources.add(no.nibio.vips.logic.modules.wheatleafblotch.WheatLeafBlotchModelService.class); diff --git a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java index 2b4bda1c285afa66108ed5c13f248bb25faa15cf..7112c88362f2b1bf8a52a31673955bc501efc646 100644 --- a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java +++ b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java @@ -19,6 +19,11 @@ package no.nibio.vips.logic.modules.barkbeetle; +import de.micromata.opengis.kml.v_2_2_0.Coordinate; +import de.micromata.opengis.kml.v_2_2_0.Document; +import de.micromata.opengis.kml.v_2_2_0.Kml; +import de.micromata.opengis.kml.v_2_2_0.KmlFactory; +import de.micromata.opengis.kml.v_2_2_0.Placemark; import java.util.List; import javax.ejb.LocalBean; import javax.ejb.Stateless; @@ -26,8 +31,9 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; +import no.nibio.vips.logic.util.GISEntityUtil; +import no.nibio.vips.logic.util.Globals; import no.nibio.vips.logic.util.SessionControllerGetter; -import org.locationtech.jts.geom.Point; /** * @copyright 2020 <a href="http://www.nibio.no/">NIBIO</a> @@ -117,4 +123,51 @@ public class BarkbeetleBean { trapsite.setTrapsiteRegistrationCollection(registrations); return em.merge(trapsite); } + + public Kml getSeasonTrapsitesKml(Integer season, Integer excludeSeasonTrapsiteId, String serverName) { + String iconPath = Globals.PROTOCOL + "://" + serverName + "/images/modules/barkbeetle/"; + List<SeasonTrapsite> traps = this.getSeasonTrapsites(season); + // Initialization + final Kml kml = KmlFactory.createKml(); + final Document document = kml.createAndSetDocument() + .withName("Barkbillefellelokaliteter").withDescription("Barkbillefellelokaliteter for sesongen " + season); + + document.createAndAddStyle() + .withId("trapsite_icon") + .createAndSetIconStyle() + .withScale(0.55) + .createAndSetIcon() + .withHref(iconPath + "dot_blue.png"); + + document.createAndAddStyle() + .withId("trapsite_icon_highlighted") + .createAndSetIconStyle() + .withScale(0.55) + .createAndSetIcon() + .withHref(iconPath + "trapsite.png"); + + String styleUrl = "#trapsite_icon"; + GISEntityUtil gisUtil = new GISEntityUtil(); + for(SeasonTrapsite trap:traps) + { + if(excludeSeasonTrapsiteId != null && excludeSeasonTrapsiteId.equals(trap.getSeasonTrapsiteId())) + { + continue; + } + final Placemark placemark = document.createAndAddPlacemark() + .withName(trap.getCountyName() + "/" + trap.getMunicipalityName()) + .withDescription( + "<ul>" + + "<li>Eier: " + trap.getOwnerName() + ", tlf: " + trap.getOwnerPhone() + "</li>" + + "<li>Registrant: <a href='mailto:" + trap.getUserId().getEmail() + "'>" + trap.getUserId().getFirstName() + " " + trap.getUserId().getLastName() + "</a>, tlf: " + trap.getUserId().getPhone() + "</li>" + + "</ul>") + .withStyleUrl(styleUrl) + .withId(trap.getSeasonTrapsiteId().toString()); + + final de.micromata.opengis.kml.v_2_2_0.Point point = placemark.createAndSetPoint(); + List<Coordinate> coord = point.createAndSetCoordinates(); + coord.add(gisUtil.getKMLCoordinateFromJTSCoordinate(trap.getGisGeom().getCoordinate())); + } + return kml; + } } diff --git a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleController.java b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleController.java index ba9f62197d5ca739ccd8d370a31f6e0c69defbf7..303af3041eb04934090c7ebb4ec784c1b6b14711 100644 --- a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleController.java +++ b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleController.java @@ -49,8 +49,6 @@ import no.nibio.vips.util.ServletUtil; import no.nibio.web.forms.FormValidation; import no.nibio.web.forms.FormValidationException; import no.nibio.web.forms.FormValidator; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.CoordinateXYZM; import org.locationtech.jts.geom.Point; /** @@ -171,6 +169,7 @@ public class BarkbeetleController extends HttpServlet { { request.setAttribute("userIsAdmin",SessionControllerGetter.getUserBean().authorizeUser(user, VipsLogicRole.BARKBEETLE_ADMIN, VipsLogicRole.BARKBEETLE_COUNTY_ADMIN, VipsLogicRole.SUPERUSER)); request.setAttribute("seasonTrapsite", trapsite); + request.setAttribute("isExtended", trapsite.getTrapsiteType().getTrapsiteTypeId().equals(TrapsiteType.TRAPSITE_TYPE_EXTENDED)); Set<Integer> missingWeeks = new HashSet(trapsite.getTrapsiteType().getTrapsiteTypeId().equals(TrapsiteType.TRAPSITE_TYPE_STANDARD)? Arrays.asList(new Integer[]{21,24,28,33}) : Arrays.asList(new Integer[]{21,24,28,33,37})); diff --git a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleService.java b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleService.java new file mode 100644 index 0000000000000000000000000000000000000000..97eb00baab00fe7e95e149f7788e6c50e01b7a1e --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleService.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.modules.barkbeetle; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import no.nibio.vips.util.ServletUtil; + +/** + * @copyright 2020 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +@Path("rest/barkbeetle") +public class BarkbeetleService { + @PersistenceContext(unitName="VIPSLogic-PU") + EntityManager em; + @Context + private HttpServletRequest httpServletRequest; + + @GET + @Path("seasontrapsites/{season}/kml") + @Produces("application/vnd.google-earth.kml+xml;charset=utf-8") + public Response getSeasonTrapsites( + @PathParam("season") Integer season, + @QueryParam("excludeSeasonTrapsiteId") Integer excludeSeasonTrapsiteId) + { + return Response.ok().entity(BarkbeetleBean.getInstance().getSeasonTrapsitesKml(season, excludeSeasonTrapsiteId, ServletUtil.getServerName(httpServletRequest))).build(); + } +} diff --git a/src/main/webapp/images/modules/barkbeetle/Instruks_Barkbillefylkeskontakter.pdf b/src/main/webapp/images/modules/barkbeetle/Instruks_Barkbillefylkeskontakter.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fb97915d688ac090c23bb22a204d78dc5942a335 Binary files /dev/null and b/src/main/webapp/images/modules/barkbeetle/Instruks_Barkbillefylkeskontakter.pdf differ diff --git a/src/main/webapp/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf b/src/main/webapp/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4fa735140bcc107cb0ef59d59787bf855e7b9d28 Binary files /dev/null and b/src/main/webapp/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf differ diff --git a/src/main/webapp/images/modules/barkbeetle/Instruks_utvidet_sesong.pdf b/src/main/webapp/images/modules/barkbeetle/Instruks_utvidet_sesong.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a22bc8e7385d482d5d169cd21d3802ccc79d61f0 Binary files /dev/null and b/src/main/webapp/images/modules/barkbeetle/Instruks_utvidet_sesong.pdf differ diff --git a/src/main/webapp/images/modules/barkbeetle/dot_blue.png b/src/main/webapp/images/modules/barkbeetle/dot_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..1fcfc846ea66b315f8ae7e0a72c47e2f4e2fcf0f Binary files /dev/null and b/src/main/webapp/images/modules/barkbeetle/dot_blue.png differ diff --git a/src/main/webapp/images/modules/barkbeetle/trapsite.png b/src/main/webapp/images/modules/barkbeetle/trapsite.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5db98a49b38563161f9f21dcadb49ad64d8600 Binary files /dev/null and b/src/main/webapp/images/modules/barkbeetle/trapsite.png differ diff --git a/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteFormMap.js b/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteFormMap.js new file mode 100644 index 0000000000000000000000000000000000000000..256c13a12cd0741468154f67c9e7910908ae004a --- /dev/null +++ b/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteFormMap.js @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + + /* + * Map with barkbeetle trap information + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ + + var map; + var trapMarker; + + function initMap(season, currentSeasonTrapsiteId, currentSeasonTrapsiteCoordinate){ + // Background layer is OpenStreetMap + var backgroundLayer = new ol.layer.Tile({ + source: new ol.source.OSM({ + attributions: [ + new ol.Attribution({ + html: mapConstants.MAP_ATTRIBUTION + }) + ] + }) + }); + + // The trapsite layer + var trapLayer = new ol.layer.Vector({ + source: new ol.source.Vector({ + url: "/rest/barkbeetle/seasontrapsites/" + season + "/kml/" + (currentSeasonTrapsiteId != null ? "?excludeSeasonTrapsiteId=" + currentSeasonTrapsiteId : ""), + projection: "EPSG:3857", + format: new ol.format.KML() + }) + }); + + // Creating the map + map = new ol.Map({ + target: 'seasonTrapsiteFormMap', + layers: [backgroundLayer, trapLayer], + //overlays: [popOverlay], + renderer: 'canvas' + }); + + // Setting zoom and center for the map (need to do this after creating map. so that we kan transform our + // center to correct map projection) + var view = new ol.View({ + center: ol.proj.transform([10.0,63.0], 'EPSG:4326', map.getView().getProjection().getCode()), + zoom: 5 + }); + map.setView(view); + + // Marker overlay + trapMarker = new ol.Overlay({ + position: currentSeasonTrapsiteId !== null ? ol.proj.transform(currentSeasonTrapsiteCoordinate, 'EPSG:4326', map.getView().getProjection().getCode()) : undefined, + positioning: 'bottom-center', + element: document.getElementById('trapMarker'), + stopEvent: false + }); + + map.addOverlay(trapMarker); + + // Listening for single clicks, position observation pin and updating form element + map.on(['singleclick'], function(evt) { + updateLocationPosition(evt.coordinate); + }); + } + + function updateLocationPosition(coordinate) +{ + var locationPosition = ol.coordinate.toStringXY(ol.proj.transform(coordinate, map.getView().getProjection().getCode(), 'EPSG:4326'),4); + // Set/move location pin + trapMarker.setPosition(coordinate); + // Update form field "location" + var locationEl = document.getElementById("gisGeom"); + //console.log(locationEl); + locationEl.value=locationPosition; + + // Adding a little animation + $("#gisGeom").animate({borderWidth: "4"},500, function(){ + $("#gisGeom").animate({borderWidth: "1"},500, function(){}); + }); + + handleLocationChanged(locationEl); +} + +/** + * Places the station marker on the coordinates given in Location input field, + * and centers the map around these coordinates + */ +function updateMarkerPosition() +{ + var locationEl = document.getElementById("gisGeom"); + + var coordinate = locationEl.value.split(","); + coordinate[0] = parseFloat(coordinate[0]); + coordinate[1] = parseFloat(coordinate[1]); + //console.log(coordinate); + var markerPosition = ol.proj.transform(coordinate, 'EPSG:4326', map.getView().getProjection().getCode()); + + trapMarker.setPosition(markerPosition); +} \ No newline at end of file diff --git a/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteListMap.js b/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteListMap.js new file mode 100644 index 0000000000000000000000000000000000000000..6ff61bda8687e699609701bbc449cff23cf92430 --- /dev/null +++ b/src/main/webapp/js/modules/barkbeetle/seasonTrapsiteListMap.js @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + + /* + * Map with barkbeetle trap information + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ + + var map; + var popOverlay; + var poiDetails; + + function initMap(season){ + // Background layer is OpenStreetMap + var backgroundLayer = new ol.layer.Tile({ + source: new ol.source.OSM({ + attributions: [ + new ol.Attribution({ + html: mapConstants.MAP_ATTRIBUTION + }) + ] + }) + }); + + // The trapsite layer + var trapLayer = new ol.layer.Vector({ + source: new ol.source.Vector({ + url: "/rest/barkbeetle/seasontrapsites/" + season + "/kml/", + projection: "EPSG:3857", + format: new ol.format.KML() + }) + }); + + // Using Bootstrap's popover plugin. See http://getbootstrap.com/javascript/#popovers + poiDetails = $("#popover"); + + // Layer for popup + popOverlay = new ol.Overlay({ + element: document.getElementById("popover") + }); + + // Creating the map + map = new ol.Map({ + target: 'seasonTrapsiteListMap', + layers: [backgroundLayer, trapLayer], + overlays: [popOverlay], + renderer: 'canvas' + }); + + // Setting zoom and center for the map (need to do this after creating map. so that we kan transform our + // center to correct map projection) + var view = new ol.View({ + center: ol.proj.transform([10.0,63.0], 'EPSG:4326', map.getView().getProjection().getCode()), + zoom: 5 + }); + map.setView(view); + + // On click, display site details in popup + map.on('singleclick', function(evt) { + var pixel = map.getEventPixel(evt.originalEvent); + displayFeatureDetails(pixel); + }); + } + + // Displays popup with forecasts for a given station + // (if there is a station where the click event is fired) + var displayFeatureDetails = function(pixel, coordinate) { + var feature = map.forEachFeatureAtPixel(pixel, function(feature,layer){ + return feature; + }); + + if (feature) { + // Position the popup, and hiding it + // Resetting information from (possible) former popups + var geometry = feature.getGeometry(); + popOverlay.setPosition(geometry.getCoordinates()); + poiDetails.popover('destroy'); + // Create the popup, showing it + poiDetails.popover({ + animation: true, + trigger: 'manual', + html: true, + placement: "auto top", + title: feature.get("name"), + content: feature.get("description") + }); + + poiDetails.popover('show'); + + + } else { + poiDetails.popover('destroy'); + } + + }; + + \ No newline at end of file diff --git a/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteForm.ftl b/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteForm.ftl index 55df07a269d6691e77fac4c0de24f8f5bf1bc689..4873122b0225948ab1f4d4c84fca8d272c21edc9 100644 --- a/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteForm.ftl +++ b/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteForm.ftl @@ -20,6 +20,9 @@ <title>Barkbilleregistrering: Rediger fellelokalitet for ${season}</title> </#macro> <#macro custom_js> + <script type="text/javascript" src="/js/constants.js"></script> + <script type="text/javascript" src="/js/3rdparty/ol.js"></script> + <script type="text/javascript" src="/js/modules/barkbeetle/seasonTrapsiteFormMap.js"></script> <script type="text/javascript" src="/js/resourcebundle.js"></script> <script src="/js/validateForm.js"></script> <script src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script> @@ -27,17 +30,17 @@ <script type="text/javascript" src="/js/3rdparty/proj4.js"></script> <script type="text/javascript"> var theForm = document.getElementById("${formId}"); - // Make sure that there is a date picker present for HTML5 - // date input fields - if (!Modernizr.inputtypes.date) { - $('input[type=date]').datepicker({ dateFormat: 'yy-mm-dd' }); - } - // Load main form definition (for validation) - loadFormDefinition("seasonTrapsiteForm","/formdefinitions/modules/barkbeetle/"); + $(document).ready(function() { + // Make sure that there is a date picker present for HTML5 + // date input fields + if (!Modernizr.inputtypes.date) { + $('input[type=date]').datepicker({ dateFormat: 'yy-mm-dd' }); + } + // Load main form definition (for validation) + loadFormDefinition("seasonTrapsiteForm","/formdefinitions/modules/barkbeetle/"); + initMap(${season},${seasonTrapsite.seasonTrapsiteId!"null"},[${(seasonTrapsite.longitude?c)!"0"},${(seasonTrapsite.latitude?c)!"0"}]); + }); - function updateMarkerPosition(){ - console.info("TODO: updateMarkerPosition"); - } function handleLocationChanged(locationField){ // Input control first @@ -71,10 +74,21 @@ fetch("/corsproxy/https://proxy1.nibio.no/municipality_cache_ws/kommuneListe/N2000/4326/2019?lon=" + lon + "&lat=" + lat) .then(response => response.json()) .then(municInfo =>{ - theForm["countyNo"].value=municInfo[0]["fylkenr"]; - theForm["countyName"].value=municInfo[0]["fylkenavn"]; - theForm["municipalityNo"].value=municInfo[0]["komnr"]; - theForm["municipalityName"].value=municInfo[0]["komnavn"]; + if(municInfo.length == 0) + { + alert("Posisjonen er utenfor Norges grenser. Vennligst korriger dette"); + theForm["countyNo"].value = 0; + theForm["countyName"].value = "Utlandet"; + theForm["municipalityNo"].value = 0; + theForm["municipalityName"].value = "Utlandet"; + } + else + { + theForm["countyNo"].value=municInfo[0]["fylkenr"]; + theForm["countyName"].value=municInfo[0]["fylkenavn"]; + theForm["municipalityNo"].value=municInfo[0]["komnr"]; + theForm["municipalityName"].value=municInfo[0]["komnavn"]; + } } ) .catch( error => console.info(error));; @@ -104,31 +118,45 @@ </#macro> <#macro custom_css> <link href="//code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" rel="stylesheet" /> + <link rel="stylesheet" type="text/css" href="/css/3rdparty/ol.css"/ > + <style type="text/css"> + #seasonTrapsiteFormMap { + height: 600px; + } + </style> </#macro> <#macro page_contents> <#if messageKey?has_content> <div class="alert alert-success">Data ble lagret ${.now}</div> </#if> + <p> + <a href="/barkbeetle?season=${season}" class="btn btn-default back" role="button">${i18nBundle.back}</a> + </p> <h1><#if seasonTrapsite.seasonTrapsiteId?has_content>Rediger<#else>Ny</#if> fellelokalitet</h1> <div class="row"> <div class="col-md-11"> - <p style="clear: left;"> - [Her trengs tekstforslag]: Barkbilleregistreringen er organisert gjennom XXX - og slik og sånn. Alle feller må være av typen BEKA (også kalt Novefella) (se bildet), og feromonet som - brukes må være av typen <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a>. Les <a href="/images/modules/barkbeetle/Instruks_2020.pdf">årets instruks</a> - og <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">monteringsanvisningen.</a> + <p>Alle feller må være av typen BEKA (=Nove, se bildet) og feromon av typen + <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a> + (=Norlure; tilsendt fra Nibio). Plasser lokaliteten med et trykk + på kartet, så genereres koordinater og flere av feltene automatisk. Alle + øvrige felt med stjerne må fylles inn. Fyll også inn dato og kommentar + nederst i skjemaet dersom montering av feller skjer senere enn 20. april. + Se utdypende informasjon i + <a href="/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf" target="new">Instruks registranter</a> + og <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">Monteringsanvisning + Beka-felle</a> + </p> + <p> + <#if seasonTrapsite.seasonTrapsiteId?has_content> + <a href="/barkbeetle?action=registerData&seasonTrapsiteId=${seasonTrapsite.seasonTrapsiteId}" class="btn btn-default" role="button">Registrer data</a> + </#if> </p> </div> <div class="col-md-1"> <img src="/images/modules/barkbeetle/Bilde_BEKA_felle.jpg" style="height: 150px;"/> </div> </div> - <p> - <a href="/barkbeetle?season=${season}" class="btn btn-default back" role="button">${i18nBundle.back}</a> - <#if seasonTrapsite.seasonTrapsiteId?has_content> - <a href="/barkbeetle?action=registerData&seasonTrapsiteId=${seasonTrapsite.seasonTrapsiteId}" class="btn btn-default" role="button">Registrer data</a> - </#if> - </p> + <div class="singleBlockContainer"> <div class="row"> <div class="col-md-8"> @@ -167,7 +195,7 @@ <button class="btn btn-default" type="button" onclick="convertProjection();">Konverter til WGS84</button> </div> </label> - <input type="text" class="form-control" id="gisGeom" name="gisGeom" placeholder="Lokalitet" value="${(seasonTrapsite.longitude?c)!""},${(seasonTrapsite.latitude?c)!""}" onblur="validateField(this);" onchange="if(validateField(this)){handleLocationChanged(this);}" /> + <input type="text" class="form-control" id="gisGeom" name="gisGeom" placeholder="Lokalitet" value="${(seasonTrapsite.longitude?c)!""},${(seasonTrapsite.latitude?c)!""}" onblur="validateField(this);" onchange="if(validateField(this)){handleLocationChanged(this);updateMarkerPosition();}" /> <span class="help-block" id="${formId}_gisGeom_validation"></span> </div> <div class="form-group"> @@ -250,9 +278,12 @@ </form> </div> <div class="col-md-4"> - Kartet kommer her! + <div id="seasonTrapsiteFormMap" class="map"> + <div id="popover"></div> + </div> </div> </div> + <div style="display: none;"><div id="trapMarker" title="Marker"><img src="/images/modules/barkbeetle/trapsite.png"/></div></div> </div> </#macro> <@page_html/> \ No newline at end of file diff --git a/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteList.ftl b/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteList.ftl index 91021c12bac72986b791558d8a1f9be5ebdb0e56..0f961def2f16c8e9ba318fd1482de80de94d4f5b 100644 --- a/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteList.ftl +++ b/src/main/webapp/templates/modules/barkbeetle/barkbeetleSeasonTrapsiteList.ftl @@ -22,16 +22,53 @@ <#macro page_contents> <h1>Fellelokaliteter for sesongen ${season}</h1> <div class="row"> - <div class="col-md-11"> - <p style="clear: left;"> - [Her trengs tekstforslag]: Barkbilleregistreringen er organisert gjennom XXX - og slik og sånn. Alle feller må være av typen BEKA (også kalt Novefella) (se bildet), og feromonet som - brukes må være av typen <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a>. Les <a href="/images/modules/barkbeetle/Instruks_2020.pdf">årets instruks</a> - og <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">monteringsanvisningen.</a> - </p> + <div class="col-md-7"> + <p>Barkbilleovervåkingen er organisert gjennom «"Barkbilleadministratorer» + ved Nibio, «Barkbillefylkeskontakter» og «Registranter». Alle feller må være + av typen BEKA (også kalt Novefella) (se bildet), og feromonet som brukes må + være av typen <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a> + (=Norlure; tilsendt fra Nibio). Les instruksjoner som + er aktuelle for deg nøye, slik som + <a href="/images/modules/barkbeetle/Instruks_Barkbillefylkeskontakter.pdf" target="new">Instruks + Barkbillefylkeskontakter</a>, + <a href="/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf" target="new">Instruks registranter</a>, og + <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">Monteringsanvisning + Beka-felle</a> (kun noen få har i tillegg + <a href="/images/modules/barkbeetle/Instruks_utvidet_sesong.pdf" target="new">utvidet + sesong</a> med egen instruksjon).</p> + + <p><strong>Barkbillefylkeskontakt</strong> oppretter her lokaliteter for sitt fylke («Legg til + ny») og tildeler disse registranter som sørger for fellemontering, tømming + av feller og fortløpende innlegging av data gjennom sesongen. Det bør være + lokaliteter i alle kommuner som tidligere har vært med (<strong>NB</strong> kommuner før + sammenslåinger etter 2012). Liste over registranter, inkludert navn/telefon + og epost, sendes tor-einar.skog@nibio.no så tidlig som mulig før sesong for + å opprette tilgang i systemet for registrantene. Etter dette får registrantene + innloggingsadgang tilsendt per epost. Se utdypende informasjon i + <a href="/images/modules/barkbeetle/Instruks_Barkbillefylkeskontakter.pdf" target="new">Instruks + Barkbillefylkeskontakter</a> (se også + <a href="/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf" target="new">Instruks + Registranter</a> for å forstå deres oppgaver).</p> + + <p><strong>Registranter</strong> må oppdatere informasjon under «Endre lokalitetsinfo» for + sin(e) lokalitet(er) så snart som mulig og sørge for at feller blir montert + innen 20. april. Fellene i standardlokaliteter tømmes etter hver av fire + perioder, dvs. på mandag eller tirsdag i ukene 21, 24, 28 og 33. Data fra + hver tømming skal legges inn under «Registrer» innen mandag i påfølgende uke, + og blir dermed del av en fortløpende kartvisning av barkbillenivået gjennom + sesongen. Se utdypende informasjon i + <a href="/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf" target="new">Instruks + Registranter</a>, og + <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">Monteringsanvisning + Beka-felle</a></p> </div> <div class="col-md-1"> - <img src="/images/modules/barkbeetle/Bilde_BEKA_felle.jpg" style="height: 150px;"/> + <img src="/images/modules/barkbeetle/Bilde_BEKA_felle.jpg" style="height: 250px;"/> + </div> + <div class="col-md-4"> + <div id="seasonTrapsiteListMap" class="map"> + <div id="popover"></div> + </div> </div> </div> <#if userIsAdmin> @@ -40,11 +77,6 @@ </p> </#if> <div class="singleBlockContainer"> - <div class="row"> - <div class="col-md-12"> - <h1>Kartet kommer her!</h1> - </div> - </div> <div class="row"> <table class="table table-striped"> <thead> @@ -80,12 +112,17 @@ </div> </#macro> <#macro custom_js> + <script type="text/javascript" src="/js/constants.js"></script> + <script type="text/javascript" src="/js/3rdparty/ol.js"></script> + <script type="text/javascript" src="/js/modules/barkbeetle/seasonTrapsiteListMap.js"></script> <script type="text/javascript"> -// TODO? +$(document).ready(function() { + initMap(${season}); +}); </script> </#macro> <#macro custom_css> - + <link rel="stylesheet" type="text/css" href="/css/3rdparty/ol.css"/ > <style type="text/css"> td.status_1 { background-color: #ffe066 !important; @@ -97,7 +134,9 @@ background-color: #ff6e66 !important; } - + #seasonTrapsiteListMap { + height: 500px; + } </style> </#macro> <@page_html/> \ No newline at end of file diff --git a/src/main/webapp/templates/modules/barkbeetle/barkbeetleTrapsiteRegistrationForm.ftl b/src/main/webapp/templates/modules/barkbeetle/barkbeetleTrapsiteRegistrationForm.ftl index c644067d1119aaacf75bbd51e9b4411777836e40..61b427f2c742f37fd9617c5e38be02179b17acd4 100644 --- a/src/main/webapp/templates/modules/barkbeetle/barkbeetleTrapsiteRegistrationForm.ftl +++ b/src/main/webapp/templates/modules/barkbeetle/barkbeetleTrapsiteRegistrationForm.ftl @@ -24,23 +24,33 @@ <#if messageKey?has_content> <div class="alert alert-success">Data ble lagret ${.now}</div> </#if> + <p> + <a href="/barkbeetle?action=editSeasonTrapsite&season=${seasonTrapsite.season}&seasonTrapsiteId=${seasonTrapsite.seasonTrapsiteId}" class="btn btn-default back" role="button">${i18nBundle.back}</a> + </p> <h1>Registrer data for lokalitet ${siteName}, sesong ${seasonTrapsite.season}</h1> <div class="row"> <div class="col-md-11"> - <p style="clear: left;"> - [Her trengs tekstforslag]: Barkbilleregistreringen er organisert gjennom XXX - og slik og sånn. Alle feller må være av typen BEKA (også kalt Novefella) (se bildet), og feromonet som - brukes må være av typen <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a>. Les <a href="/images/modules/barkbeetle/Instruks_2020.pdf">årets instruks</a> - og <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">monteringsanvisningen.</a> + <p> + Påse at + </p> + <ul> + <li>alle feller er av typen <strong>BEKA</strong> (=Nove, se bildet) og feromon av typen + <a href="http://kjemikonsult.no/Norsk/Produkter.html" target="new">Ipslure</a> + (= Norlure; tilsendt fra Nibio).</li> + <li>antall biller legges inn for rett tømmeperiode i rett ukenummer</li> + <li>tallet legges inn på rett sted, som enten antall biller eller antall ml (volum målt med målebeger; omregning til antall biller skjer automatisk).</li> + </ul> + <p> + Se utdypende informasjon i + <a href="/images/modules/barkbeetle/Instruks_registranter_i_Barkbilleovervakingen.pdf" target="new">Instruks registranter</a> + og <a href="/images/modules/barkbeetle/Montering_av_barkbillefelle.pdf">Monteringsanvisning + Beka-felle</a> </p> </div> <div class="col-md-1"> <img src="/images/modules/barkbeetle/Bilde_BEKA_felle.jpg" style="height: 150px;"/> </div> </div> - <p> - <a href="/barkbeetle?action=editSeasonTrapsite&season=${seasonTrapsite.season}&seasonTrapsiteId=${seasonTrapsite.seasonTrapsiteId}" class="btn btn-default back" role="button">${i18nBundle.back}</a> - </p> <#if userIsAdmin> <div class="alert alert-info">Registrant: <strong>${seasonTrapsite.userId.firstName} ${seasonTrapsite.userId.lastName}</strong>, tlf <strong>${seasonTrapsite.userId.phone!"Ikke oppgitt"}</strong>, e-post <strong>${seasonTrapsite.userId.email}</strong></div> </#if> @@ -84,10 +94,10 @@ <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap1" value="${reg.trap1!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> <td><input class="form-control" type="number" name="${reg.trapsiteRegistrationPK.week}_trap2_ml" onblur="setCalculatedAmount(this);" value=""<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap2" value="${reg.trap2!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td><input class="form-control" type="number" name="${reg.trapsiteRegistrationPK.week}_trap3_ml" onblur="setCalculatedAmount(this);" value=""<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap3" value="${reg.trap3!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td><input class="form-control" type="number" name="${reg.trapsiteRegistrationPK.week}_trap4_ml" onblur="setCalculatedAmount(this);" value=""<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap4" value="${reg.trap4!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> + <td><input class="form-control" type="number" name="${reg.trapsiteRegistrationPK.week}_trap3_ml" onblur="setCalculatedAmount(this);" value=""<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> + <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap3" value="${reg.trap3!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> + <td><input class="form-control" type="number" name="${reg.trapsiteRegistrationPK.week}_trap4_ml" onblur="setCalculatedAmount(this);" value=""<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> + <td><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap4" value="${reg.trap4!"M"}"<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> <td rowspan="2"> <#if reg.dateRegistration?has_content> @@ -105,8 +115,8 @@ <tr> <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap1Remarks" placeholder="Kommentar felle 1" value="${reg.trap1Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap2Remarks" placeholder="Kommentar felle 2" value="${reg.trap2Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap3Remarks" placeholder="Kommentar felle 3" value="${reg.trap3Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> - <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap4Remarks" placeholder="Kommentar felle 4" value="${reg.trap4Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek> disabled="disabled"</#if>/></td> + <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap3Remarks" placeholder="Kommentar felle 3" value="${reg.trap3Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> + <td colspan="2"><input class="form-control" type="text" name="${reg.trapsiteRegistrationPK.week}_trap4Remarks" placeholder="Kommentar felle 4" value="${reg.trap4Remarks!""}"<#if reg.trapsiteRegistrationPK.week gt currentWeek || isExtended> disabled="disabled"</#if>/></td> </tr> </#list>