diff --git a/src/main/webapp/css/map.css b/src/main/webapp/css/map.css index 8d9bbf5079874e3056ac9e42b0b0801387ab7808..bc900d0ef01457267b206962de1f63c581b3a6ce 100755 --- a/src/main/webapp/css/map.css +++ b/src/main/webapp/css/map.css @@ -35,7 +35,6 @@ rgba(255, 255, 255, 0.4); z-index:100; } - #layerswitcher { margin:0; padding:10px; @@ -43,4 +42,44 @@ background:rgba(0, 60, 136, 0.5); list-style-type:none; } - + +.geo-location { + position: absolute; + top: 4.5em; + left: 0.5em; + text-align: left; +} + +.geo-location .panel { + padding-right: 50px; + border: 1px solid #cccccc; + background-color: white; + margin: 0; + display: none; +} + +.geo-location.shown .panel { + display: block; +} + +.geo-location button { + float: right; + width: 38px; + height: 38px; + background-image: url('../images/geoloc3.png'); + background-size: 20px 20px; + background-repeat: no-repeat; + background-position: 1px; + background-color: white; + border: none; +} + +.geo-location button:focus, .geo-location button:hover { + background-color: white; +} + +.clearOneActive { + background-color: #009933 !important; + color: white; +} + diff --git a/src/main/webapp/images/geoloc2.png b/src/main/webapp/images/geoloc2.png new file mode 100755 index 0000000000000000000000000000000000000000..89b85343d3c0780004f51c20df6bc0b4d25e2c2e Binary files /dev/null and b/src/main/webapp/images/geoloc2.png differ diff --git a/src/main/webapp/images/geoloc3.png b/src/main/webapp/images/geoloc3.png new file mode 100755 index 0000000000000000000000000000000000000000..6cc091a3fd8200e936ab1531b5da32c631995640 Binary files /dev/null and b/src/main/webapp/images/geoloc3.png differ diff --git a/src/main/webapp/js/observationFormMap.js b/src/main/webapp/js/observationFormMap.js index 1857185afa6f0a931df54cdd116dd8ebe13e6459..e3371bab3314d91158d7d501f7073458425a5693 100755 --- a/src/main/webapp/js/observationFormMap.js +++ b/src/main/webapp/js/observationFormMap.js @@ -70,14 +70,17 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { } }) }); - - //-----------------Get maplayers you can choose from----------------------------- + + + + //########################Get maplayers you can choose from######################## //var layersObj = eval ("(" + chooseLayersObj + ")"); var allLayers = [osm, bingArial, topo2graatone] ; var chooseLayers = []; var choosenLayer; var hoverAttribute = ''; + var deleteObj = false; var typeSelect = document.getElementById('type'); @@ -104,11 +107,70 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { } allLayers.push.apply(allLayers, chooseLayers); + + +window.app = {}; +var app = window.app; + + +// +// Define rotate to north control. +// + + + +/** + * @constructor + * @extends {ol.control.Control} + * @param {Object=} opt_options Control options. + */ +app.geoLocationControl = function(opt_options) { + + var options = opt_options || {}; + + var button = document.createElement('button'); + //button.innerHTML = 'O'; + button.title = 'Show me where I am' + + var this_ = this; + + var handleGeoLocation = function(e) { + /*if (geolocation.getTracking()){ + geolocation.setTracking(false); + geoOverlay.getSource().clear(true); + } else {*/ + removeMouseOver(); + geolocation.setTracking(true); + //} + }; + + button.addEventListener('click', handleGeoLocation, false); + button.addEventListener('touchstart', handleGeoLocation, false); + + var element = document.createElement('div'); + element.className = 'ol-unselectable ol-control geo-location'; + element.appendChild(button); + + ol.control.Control.call(this, { + element: element, + target: options.target + }); + +}; +ol.inherits(app.geoLocationControl, ol.control.Control); + // Creating the map map = new ol.Map({ target: 'observationFormMap', + controls: ol.control.defaults({ + attributionOptions: /** @type {olx.control.AttributionOptions} */ ({ + collapsible: true + }) + }).extend([ + new app.geoLocationControl() + ]), layers: allLayers, renderer: 'canvas' }); @@ -179,9 +241,16 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { }) }); + function computeFeatureStyle(feature, resolution) { return [new ol.style.Style({ + image: new ol.style.Circle({ + radius: 10, + fill: new ol.style.Fill({ + color: 'rgba(0, 0, 255, 0.5)' + }) + }), fill: new ol.style.Fill({ color: 'rgba(0, 0, 255, 0.2)' }), @@ -213,7 +282,7 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { style: computeFeatureStyle }); - mouseOverlay.setMap(map); + if (drawnObjs) { // Get drawn objs param from initMap var format = new ol.format.GeoJSON(); @@ -226,6 +295,7 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { } featureOverlay.setMap(map); + mouseOverlay.setMap(map); var modify = new ol.interaction.Modify({ features: features, @@ -248,15 +318,31 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { map.addInteraction(draw); } + var pointerMoveId; + function removeMouseOver(){ + map.unByKey(pointerMoveId); + mouseOverlay.getSource().clear(true); + } + function chooseFromLayer(chooseLayer) { - map.removeInteraction(draw); - chooseLayer.setVisible(true); - //map.addInteraction(selectInteraction); + map.removeInteraction(draw); + map.removeInteraction(modify); + chooseLayer.setVisible(true); + var clickInfo = function(pixel) { var features = []; - map.forEachFeatureAtPixel(pixel, function(feature, layer) { - featureOverlay.getSource().addFeature(feature); + map.forEachFeatureAtPixel(pixel, function(feature) { + + if (deleteObj){ + featureOverlay.getSource().removeFeature(feature); + setTimeout(function() { //wait until feature is removed + mouseOverlay.getSource().clear(true); + }, 100); + + }else { + featureOverlay.getSource().addFeature(feature); + } }); }; @@ -267,13 +353,13 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { var mouseInfo = function(pixel) { var features = []; + mouseOverlay.getSource().clear(true); map.forEachFeatureAtPixel(pixel, function(feature, layer) { - mouseOverlay.getSource().clear(true); mouseOverlay.getSource().addFeature(feature); }); }; - map.on('pointermove', function(evt) { + pointerMoveId = map.on('pointermove', function(evt) { var pixel = evt.pixel; mouseInfo(pixel); }); @@ -287,6 +373,7 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { */ typeSelect.onchange = function(e) { map.removeInteraction(draw); + deleteObj = false; for (i = 0; i < chooseLayers.length; i++) { if (parseInt(e.target.value) === chooseLayers[i].getProperties().id) { @@ -300,7 +387,8 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { } if (e.target.value === 'Point' || e.target.value === 'Polygon'){ map.addInteraction(modify); - addDrawInteraction(); + addDrawInteraction(); + removeMouseOver(); } }; @@ -308,9 +396,10 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { - $('#save-button').click(function() { + /* $('#save-button').click(function() { // get the features drawn on the map - var features = featureOverlay.getSource().getFeatures(); + var features = null; + features = featureOverlay.getSource().getFeatures(); var format = new ol.format.GeoJSON(); // write features to GeoJSON format using projection EPSG:4326 @@ -320,7 +409,9 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { }); alert(result); - }); + });*/ + + @@ -334,8 +425,41 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { // clears the map and the output of the data function clearMap() { featureOverlay.getSource().clear(true); + geoOverlay.getSource().clear(true); + //geolocation.setTracking(false); } + $('#deleteOne').click(function() { + deleteObj = !deleteObj; // toggle + if (deleteObj){ + $('#deleteOne').addClass('clearOneActive'); + chooseFromLayer(featureOverlay); + //map.removeInteraction(modify); + //map.removeInteraction(draw); + } else { + $('#deleteOne').removeClass('clearOneActive'); + removeMouseOver(); + mouseOverlay.getSource().clear(true); + addDrawInteraction(); + } + + }); + + function removeFeature(featureID) { + + var features = featureOverlay.getSource().getFeatures(); + if (features != null && features.length > 0) { + for (x in features) { + var id = features[x].getProperties().id; + if (id == featureID) { + featureOverlay.getSource().removeFeature(features[x]); + geoOverlay.getSource().clear(true); + break; + } + } + } + } + // creates unique id's function uid() { var id = 0; @@ -350,6 +474,45 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { //######################## GEOLOCATION ############# + var geoPosStyle = new ol.style.Style({ + fill: new ol.style.Fill({ + color: 'rgba(0, 0, 255, 0.1)' + }), + stroke: new ol.style.Stroke({ + color: 'rgba(0, 0, 255, 0.5)', + width: 2 + }), + image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({ + anchor: [13, 13], + anchorXUnits: 'pixels', + anchorYUnits: 'pixels', + opacity: 1, + src: 'images/geoloc2.png' + })) + }); + + + var geoFeatures = new ol.Collection(); + geoOverlay = new ol.layer.Vector({ + source: new ol.source.Vector({ + features: geoFeatures + }), + style: geoPosStyle + }); + + geoOverlay.setMap(map); + + + + +/* var element = document.createElement('div'); + element.className = 'ol-unselectable ol-control geo-location'; + + var button = document.createElement('button'); + button.setAttribute('title', tipLabel); + element.appendChild(button); + +*/ var geolocation = new ol.Geolocation({ projection: view.getProjection() }); @@ -358,35 +521,62 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { return document.getElementById(id); } - el('track').addEventListener('change', function() { - geolocation.setTracking(this.checked); - $('#type').val('Point'); - for (i = 0; i < chooseLayers.length; i++) { - chooseLayers[i].setVisible(false); - } - }); - // handle geolocation error. geolocation.on('error', function(error) { alert(error.message); }); + function showalert(message,alerttype) { + + $('#alert_placeholder').append('<div id="alertdiv" class="alert alert-danger fade in"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>') + setTimeout(function() { // this will automatically close the alert and remove this if the users doesnt close it in 5 secs + $("#alertdiv").remove(); + }, 5000); + } + geolocation.on('change:position', function() { + + removeFeature('geoLoc'); + var coordinates = geolocation.getPosition(); + var accuracy = geolocation.getAccuracy(); + if(accuracy > 500){ + showalert('Geolocation accuracy (blue circle) is larger than 500, accuracy now: '+accuracy,'alert-error') + } + + var geoExtent = [ + coordinates[0] - accuracy - 100, + coordinates[1] - accuracy - 100, + coordinates[0] + accuracy + 100, + coordinates[1] + accuracy + 100 + ]; var posFeature = new ol.Feature({ - geometry: new ol.geom.Point(coordinates) + geometry: new ol.geom.Point(coordinates), }); - + posFeature.set('id', 'geoLoc'); + featureOverlay.getSource().addFeature(posFeature); + geoOverlay.getSource().addFeature(posFeature); + + + var accuracyFeature = new ol.Feature(); + geolocation.on('change:accuracyGeometry', function() { + accuracyFeature.setGeometry(geolocation.getAccuracyGeometry()); + }); + + geoOverlay.getSource().addFeature(accuracyFeature); var numFeatures = featureOverlay.getSource().getFeatures().length; + if (numFeatures > 1) { //Zoom to all features var extent = featureOverlay.getSource().getExtent(); map.getView().fit(extent, map.getSize()); + } else if (geoExtent) { //Zoom to accuracy circle + map.getView().fit(geoExtent, map.getSize()); } else { //Zoom to geolocation map.getView().setCenter(coordinates); map.getView().setZoom(15); @@ -395,18 +585,19 @@ function initMap(center, zoomLevel, displayMarker, drawnObjs, chooseLayersObj) { map.addInteraction(modify); addDrawInteraction(); - - }); + geolocation.setTracking(false); + + }); /*function updateLocationPosition(coordinate) { - var locationPosition = ol.coordinate.toStringXY(ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326'), 8); + //var locationPosition = ol.coordinate.toStringXY(ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326'), 8); // Set/move location pin marker.setPosition(coordinate); // Update form field "location" - var locationEl = document.getElementById("location"); - locationEl.setAttribute("value", locationPosition); + //var locationEl = document.getElementById("location"); + //locationEl.setAttribute("value", locationPosition); // Adding a little animation $("#location").animate({ borderWidth: "4" diff --git a/src/main/webapp/templates/observationForm.ftl b/src/main/webapp/templates/observationForm.ftl index d99494cde3602213450056f88789a9236bb9c9a3..bef0cd52bfff9d60e2f953a793100d23538170c4 100755 --- a/src/main/webapp/templates/observationForm.ftl +++ b/src/main/webapp/templates/observationForm.ftl @@ -135,12 +135,11 @@ <option value="Polygon">Polygon</option> </select> <button id="delete" type="button">Clear all</button> + <button id="deleteOne" type="button">Clear one</button> </div> <div id="observationFormMap" class="map"> </div> - <label class="checkbox" for="track"> - <input id="track" type="checkbox"/>Show me where I am - </label> + <div id="alert_placeholder"></div> </div> </div> <div style="display: none;"><div id="marker" title="Marker"><img src="/images/bug_medium.png"/></div></div>