Skip to content
Snippets Groups Projects
map.js 19.51 KiB
// The globally available map object
var map, featureOverlay, newFeatureOverlay; 

// Override localization settings for this particular web page
var hardcodedLanguage = "nb";

// If false, touching map will not create a new item
var registration = false;

function initMap()
{
    
    var features = new ol.Collection();

var iconRadius = 10;
    
var styles = {
    // Bulkemispel = rød
    'cotoneaster bullatus': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [255,0,0,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })],
    // Sprikemispel = dyp oransje
    'cotoneaster divaricata': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [239,133,19,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })],
    // Pilemispel = gul
    'cotoneaster salicifolia': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [239,236,19,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })],
    // Eple = grønn
    'malus domestica': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [0,255,0,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })],
    // Pære = grågrønn
    'pyrus communis': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [122,175,131,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })],
    // Planteriket = blå 
    'plantae': [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [0,0,255,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
            radius: iconRadius
        })
    })]
};
  
  featureOverlay = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: features
    }),
    style: function(feature, resolution){
        if(feature.get("cropOrganism") != null && feature.get("cropOrganism")["latinName"] != null)
        {
            return styles[feature.get("cropOrganism")["latinName"].toLowerCase()];
        }
        else 
        {
            return styles["plantae"];
        }
    }
            
  });
  
  newFeatureOverlay = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: new ol.Collection()
    }),
    style: [new ol.style.Style({
        image: new ol.style.Circle({
            fill: new ol.style.Fill({ color: [255,255,255,1] }),
            stroke: new ol.style.Stroke({ color: [0,0,0,1], width: 3, lineDash: [2,2] }),
            radius: 10
        })
    })]
            
  });
  
  
  var parser = new ol.format.WMTSCapabilities();
  fetch('https://opencache.statkart.no/gatekeeper/gk/gk.open_wmts?Version=1.0.0&service=wmts&request=getcapabilities').then(function(response) {
        return response.text();
      }).then(function(text) {
        var result = parser.read(text);
        var options = ol.source.WMTS.optionsFromCapabilities(result, {
          layer: 'topo4',
          matrixSet: 'EPSG:3857'
        });
        var topo4 = 
          new ol.layer.Tile({
            opacity: 1,
            source: new ol.source.WMTS(/** @type {!olx.source.WMTSOptions} */ (options))
          });
          
  
        map = new ol.Map({
              target: 'map',
              layers: [
                //topo2graatone, 
                topo4,
                //osm,
                featureOverlay,
                newFeatureOverlay
              ],
              view: new ol.View({
                center: ol.proj.fromLonLat([8.5, 60.8]),
                zoom: 6
              })
            });

        // TODO feature properties must be synchronized
        var lastYear = new Date().getFullYear() - 1;
        // Population the season select list, setting last year as default selected
        initSeasonSelectList(lastYear);
        getAndRenderObservations(lastYear);


        map.on('click', function(evt){
                //features = []
                var feature = map.forEachFeatureAtPixel(
                    evt.pixel, function(ft, l) { return ft; }
                );

                var vectorSource = newFeatureOverlay.getSource();
                // Remove any new features already created
                vectorSource.clear();

                if (feature) {
                    // Create a fake icon for highlighting
                    var fakeFeature = createFeature(feature.getGeometry().getCoordinates());
                    vectorSource.addFeature(fakeFeature);
                    displayFeature(feature);   
                }
                else if(registration)
                {
                    var newFeature = createFeature(map.getCoordinateFromPixel(evt.pixel));
                    vectorSource.addFeature(newFeature);
                    editFeature(newFeature.getId());
                }
        });
    
    }); // END FETCH
    
}

/**
 * 
 * @param {type} fromSeason
 * @returns {undefined}
 */
function getAndRenderObservations(fromSeason)
{
    //console.info("getAndRenderObservations(" + season + ")");
    $.getJSON("/rest/observation/filter/1/geoJSON?from=" + fromSeason + "-01-01&pestId=" + paerebrann.organismId, function(geoData){
        //console.info(geoData)
        var format = new ol.format.GeoJSON();

        var drawnfeatures = format.readFeatures(geoData, {
          //dataProjection: "EPSG:32633",
          dataProjection: "EPSG:4326",
          featureProjection: map.getView().getProjection().getCode()
        });
        featureOverlay.getSource().clear();
        featureOverlay.getSource().addFeatures(drawnfeatures);
    });
}

function toggleRegistration(theButton)
{
    if(registration)
    {
        theButton.title = "Registrering er AV";
        theButton.style.color="white";
    }
    else
    {
        theButton.title = "Registrering er PÅ";
        theButton.style.color="red";
    }
    registration = ! registration;
}

/**
 * Creates a new feature
 * @param {type} coordinate
 * @returns {createFeature.newFeature|ol.Feature}
 */
var createFeature = function(coordinate)
{
    if(coordinate.length == 2)
    {
        coordinate = [coordinate[0],coordinate[1],0];
    }
    var point = new ol.geom.Point(coordinate);
    var newFeature = new ol.Feature({
        name: "Ny observasjon",
        geometry: point
    });
    newFeature.setId(-1);
    newFeature.setProperties({
            "observationId": -1,
            "observationData": "{\"symptom\":\"\",\"tiltak\":\"\",\"forekomststorrelse\":\"\"}",
            "cropOrganism": {},
            "observationText" : "",
            "timeOfObservation": moment().valueOf()
        });
    
    return newFeature;
}

var displayFeature = function(feature)
{
    var featureForm = document.getElementById("featureForm");
    
    var observationData = JSON.parse(feature.get("observationData"));
    var timeOfObservation = new moment(feature.get("timeOfObservation"));
    var html = [
        '<button type="button" onclick="unFocusForm()">X</button>',
        '<button type="button" onclick="editFeature(\'', feature.getId() ,'\');">Rediger</button>',
        '<button type="button" onclick="deleteFeature(' + feature.getId() + ')">Slett</button>',
        '<h3>Registrering</h3>',
        '<table>',
        '<tr><td>Type</td><td>',getLocalizedOrganismName(feature.get("cropOrganism"),hardcodedLanguage),'</td></tr>',
        '<tr><td>Størrelse</td><td>',observationData["forekomststorrelse"],'</td></tr>',
        '<tr><td>Symptom</td><td>',observationData["symptom"],'</td></tr>',
        '<tr><td>Tiltak</td><td>',observationData["tiltak"],'</td></tr>',
        '<tr><td>Beskrivelse</td><td>',feature.get("observationText"),'</td></tr>',
        '<tr><td>Dato</td><td>',timeOfObservation.format("DD.MM.YYYY"),'</td></tr>',
        '</table>'
    ];
    featureForm.innerHTML = html.join("");
    focusForm();
}

var forekomsttypeLatinskeNavn = [
    "Cotoneaster bullatus", //"Bulkemispel", 
    "Malus domestica", //"Eple", 
    "Pyrus communis", //"Pære", 
    "Cotoneaster salicifolia", //"Pilemispel", 
    "Cotoneaster divaricata", //"Sprikemispel", 
    "Plantae" // Planteriket (Annet)
];

var forekomsttyper = [];
var paerebrann = {};

function initForekomsttyper()
{
    $.getJSON("/rest/organism/search/latinnames?keywords=" + forekomsttypeLatinskeNavn.join(","), function(data){
       forekomsttyper = data; 
    });
}

function initPaerebrann(){
    $.getJSON("/rest/organism/search/latinnames?keywords=Erwinia amylovora", function(data){
       if(data.length == 1)
       {
           paerebrann = data[0];
           initMap();
       }
    });
}

var getCropOrganism = function(organismId)
{
    for(var i=0;i<forekomsttyper.length;i++)
    {
        if(forekomsttyper[i].organismId == organismId)
        {
            return forekomsttyper[i];
        }
    }
}

var forekomststorrelses = ["Ikke bestemt", "1 plante", "10 planter", "100 planter", "Mer enn 100 planter"];
var symptoms = ["Ikke symptom", "Symptom"];
var tiltaks = ["Ikke ryddet", "Ryddet"];


var editFeature = function(featureId)
{
    var feature = featureId > 0 ? featureOverlay.getSource().getFeatureById(featureId)
                                    : newFeatureOverlay.getSource().getFeatureById(featureId);
    var observationData = JSON.parse(feature.get("observationData"));
    var timeOfObservation = new moment(feature.get("timeOfObservation"));
    var featureForm = document.getElementById("featureForm");
    var html = 
        '<button type="button" onclick="unFocusForm()" title="Avbryt">X</button>' +
        (featureId > 0 ? '<button type="button" onclick="deleteFeature(' + featureId + ')">Delete</button>' : '') +
        '<h3>' + (featureId > 0 ? "R" : "Ny r") + 'egistrering</h3>' +
        '<table>' +
        '<tr><td>Type</td><td>' +
        generateCropSelect("forekomsttype", forekomsttyper, feature.get("cropOrganism")["organismId"]) +           
        '</td></tr>' +
        '<tr><td>Størrelse</td><td>' +
        generateSelect("forekomststorrelse", forekomststorrelses, observationData["forekomststorrelse"]) +           
        '</td></tr>' +
        '<tr><td>Symptom</td><td>' +
        generateSelect("symptom", symptoms, observationData["symptom"]) + 
        '</td></tr>' +
        '<tr><td>Tiltak</td><td>' + 
        generateSelect ("tiltak", tiltaks, observationData["tiltak"]) + 
        '</td></tr>' +
        '<tr><td>Beskrivelse</td><td>' + 
        '<textarea id="beskrivelse" name="beskrivelse">' + (feature.get("observationText") != null ? feature.get("observationText") : "")  + '</textarea>' +
        '</td></tr>' +
        '<tr><td>Dato</td><td>' +
        '<input type="text" id="dato" name="dato" size="10" value="'+ timeOfObservation.format("DD.MM.YYYY") + '"/></td></tr>' +
        '<tr><td></td><td>' +
        '<input type="submit" value="Lagre" onclick="storeFeature(' + feature.getId() + ');"/></td></tr>' +
        '</table>';
        
    
    featureForm.innerHTML = html;
    focusForm();
    //console.info(feature);
};

var storeFeature = function(featureId)
{
    var feature = featureId > 0 ? featureOverlay.getSource().getFeatureById(featureId)
                                    : newFeatureOverlay.getSource().getFeatureById(featureId);
    
    // Store, clear newFeature layer
    // Need to add feature as payload
    var format = new ol.format.GeoJSON();
    
    // Add the form data
    var cropOrganism = getCropOrganism(document.getElementById("forekomsttype").options[document.getElementById("forekomsttype").options.selectedIndex].value);
    //console.info(cropOrganism);
    var forekomststorrelse = document.getElementById("forekomststorrelse").options[document.getElementById("forekomststorrelse").options.selectedIndex].value;
    var symptom = document.getElementById("symptom").options[document.getElementById("symptom").options.selectedIndex].value;
    var tiltak = document.getElementById("tiltak").options[document.getElementById("tiltak").options.selectedIndex].value;
    var observationText = document.getElementById("beskrivelse").value;
    var observationHeading = "Registrering av pærebrann";
    var timeOfObservation = moment(document.getElementById("dato").value + "+0200","DD.MM.YYYYZ").valueOf();
    
    feature.setProperties({
       timeOfObservation: timeOfObservation,
       cropOrganism: cropOrganism,
       organism: paerebrann,
       observationHeading: observationHeading,
       observationText: observationText,
       observationData: "{\"symptom\":\"" + symptom + "\",\"tiltak\":\"" + tiltak + "\",\"forekomststorrelse\":\"" + forekomststorrelse + "\"}",
       statusTypeId: 3,
       statusRemarks: "Registrert via pærebrannovervåkningskartet",
       isQuantified: true,
       broadcastMessage: false
    });
    var result = format.writeFeatures([feature], {
        dataProjection: 'EPSG:4326',
        featureProjection: map.getView().getProjection().getCode()
      });
    
    //console.log(feature);
    
    $.ajax({
        type: "POST",
        url: "/rest/observation/gisobservation",
        // The key needs to match your method's input parameter (case-sensitive).
        data: result,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(geoData){
            //console.info(geoData)
            var format = new ol.format.GeoJSON();

            var drawnfeatures = format.readFeatures(geoData, {
              dataProjection: "EPSG:4326",
              featureProjection: map.getView().getProjection().getCode()
            });
            newFeatureOverlay.getSource().clear(true);
            // If storing an existing feature, remove the one
            // that was there before storing, since the returned
            // one has a new gisId (featureId)
            if(featureId > 0)
            {
                featureOverlay.getSource().removeFeature(feature);
            }
            featureOverlay.getSource().addFeatures(drawnfeatures);
            unFocusForm();
        },
        error: function( jqXHR, textStatus, errorThrown) {
            if(jqXHR.status == 401)
            {
                if(confirm("Kan ikke lagre fordi du er logget ut av applikasjonen. Klikk OK for å logge inn."))
                {
                    window.location.reload();
                }
            }
            else
            {
                alert("Beklager, en feil oppsto. Status = " + jqXHR.status + ", eventuell feilmelding: " + textStatus);
            }
        }
    });
    
    
}
/**
 * Delete an existing feature
 * @param {type} featureId
 * @returns {undefined}
 */
var deleteFeature = function(featureId)
{
    if(!confirm("Er du sikker på at du vil slette?"))
    {
        return;
    }
    
    var feature = featureOverlay.getSource().getFeatureById(featureId);
    
    $.ajax({
        type: "DELETE",
        url: "/rest/observation/gisobservation/" + feature.getId(),
        success: function(response){
            console.info(response);
            // If storing an existing feature, remove the one
            // that was there before storing, since the returned
            // one has a new gisId (featureId)
            if(featureId > 0)
            {
                featureOverlay.getSource().removeFeature(feature);
            }
            unFocusForm();
        },
        error: function( jqXHR, textStatus, errorThrown) {
            if(jqXHR.status == 401)
            {
                if(confirm("Kan ikke slette fordi du er logget ut av applikasjonen. Klikk OK for å logge inn."))
                {
                    window.location.reload();
                }
            }
            else
            {
                alert("Beklager, en feil oppsto. Status = " + jqXHR.status + ", eventuell feilmelding: " + textStatus);
            }
        }
    });
}

var generateSelect = function(selectName, options, preselect)
{
    var retVal = '<select id="' + selectName + '" name="' + selectName + '">';
    for(var i=0; i< options.length; i++)
    {
        retVal += '<option value="' + options[i] + '"' + (options[i] == preselect ? " selected=\"selected\"" : "") + '">' + options[i]  + '</option>';
    }
    retVal += '</select>';
    return retVal;
}

var generateCropSelect = function(selectName, cropOrganisms, preselect)
{
    var retVal = '<select id="' + selectName + '" name="' + selectName + '">';
    for(var c=0; c < forekomsttypeLatinskeNavn.length; c++)
    {
        currentLatinName = forekomsttypeLatinskeNavn[c];
        for(var i=0; i< cropOrganisms.length; i++)
        {
            if(cropOrganisms[i].latinName == currentLatinName)
            {
                retVal += '<option value="' + cropOrganisms[i].organismId + '"' + (cropOrganisms[i].organismId == preselect ? " selected=\"selected\"" : "") + '">' + 
                        (currentLatinName == "Plantae" ? "Annet" : getLocalizedOrganismName(cropOrganisms[i], hardcodedLanguage))  
                        + '</option>';
            }
        }
    }
    retVal += '</select>';
    return retVal;
}

var focusForm = function()
{
    var featureForm = document.getElementById("featureForm");
    featureForm.style.display = "block";
}

var unFocusForm = function()
{
    var featureForm = document.getElementById("featureForm");
    featureForm.style.display = "none";
    // Also remove feature (if one) on the New feature overlay
    newFeatureOverlay.getSource().clear();
}

var navigateTo = function(center)
{
    var centerPosition = ol.proj.transform(center, 'EPSG:4326', 'EPSG:3857');
        view = new ol.View({
        center: centerPosition,
        zoom: 18
      });

      map.setView(view);
   
    var searchResultsEl = document.getElementById("searchResults");
    searchResultsEl.innerHTML = "";
    searchResultsEl.style.display="none";
};

function navToLocation() {
    if (navigator.geolocation) {
        if(window.location.protocol === "https:")
        {
            navigator.geolocation.getCurrentPosition(function(geopositionObj){
                navigateTo([geopositionObj.coords.longitude, geopositionObj.coords.latitude]);
                }
            );
        }
        else
        {
            if(confirm("Lokalisering fungerer bare over https (sikker tilkobling mellom nettleser og tjener). Klikk OK for å gå til sikker tilkobling."))
            {
                window.location = "https:" + window.location.href.substring(window.location.protocol.length);
            }
        }
    } else {
        alert( "Lokaliseringsfunksjonen er ikke tilgjengelig i denne nettleseren.");
    }
}

/**
 * 
 * @param {type} selectedSeason
 * @returns {undefined}
 */
function initSeasonSelectList(selectedSeason)
{
    // What's the current year?
    var thisYear = new Date().getFullYear();
    // How many years do we go back?
    $.ajax({
        url: "/rest/observation/first/" + paerebrann.organismId
        })
    .done(function(data){
       var time = moment(data);
       var firstYear = time.toDate().getFullYear();
       // Loop gjennom år, lag valgliste :-)
       var startSeasonList = document.getElementById("startSeason");
       for(var i=firstYear;i<=thisYear;i++)
       {
           var yearOpt = new Option("",i);
           yearOpt.innerHTML = i + " &rarr;"
           if(i==selectedSeason)
           {
               yearOpt.selected=true;
           }
           startSeasonList.options[startSeasonList.options.length] = yearOpt;
       }
    })
    .fail(function(jqXHR, textStatus, errorThrown){
        alert(textStatus);
    });
    
}