From aa293da1f8f58994bd3320b5bafe02731c23603d Mon Sep 17 00:00:00 2001 From: jshjelse <jshjelse@stud.ntnu.no> Date: Sun, 31 Dec 2023 10:44:13 +0100 Subject: [PATCH] Ferdigstille --- css/style.css | 5 + index.html | 62 +++++++- javascript/exampleData/points.geojson | 35 +++++ javascript/heatmap.js | 28 ++++ javascript/leaflet-heat.js | 11 ++ javascript/mapChange.js | 67 ++------ javascript/pointMap.js | 218 ++++++++++++++++++++++++++ javascript/tin.js | 23 +-- javascript/voronoi.js | 57 +++++-- 9 files changed, 430 insertions(+), 76 deletions(-) create mode 100644 javascript/exampleData/points.geojson create mode 100644 javascript/heatmap.js create mode 100644 javascript/leaflet-heat.js create mode 100644 javascript/pointMap.js diff --git a/css/style.css b/css/style.css index 95ae4c6..ac526df 100644 --- a/css/style.css +++ b/css/style.css @@ -46,6 +46,11 @@ p { flex-grow: 2; flex-direction: row; } +.box4 { + display: flex; + flex-grow: 4; + flex-direction: row; +} .button { font-family: monospace; diff --git a/index.html b/index.html index 64f15a1..f34b0a0 100644 --- a/index.html +++ b/index.html @@ -38,9 +38,10 @@ <button class="button" onclick="openBox('unionBox')">Union</button> </div> <div id="buttons2" class="box2" style="display: none;"> - <p style="width: 32vw;"></p> + <p style="width: 25vw;"></p> <button class="button" onclick="TIN()">TIN</button> <button class="button" onclick="voronoi()">Voronoi</button> + <button class="button" onclick="heatmap()">Heatmap</button> </div> </div> @@ -270,6 +271,47 @@ <p id="tutorial" class="tutorial"></p> </div> + + <div id="loadPointsBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Load points</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('loadPointsBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> + + <button id="examplePoints" class="onClick" style="line-height: 10vh;" onclick="handleDefaultPoints()">Load example points</button> + + <input id="fileInput2" type="file" accept=".geojson" style="display: none;"> + <button id="loadPoints" class="onClick" style="margin-top: 2vh; line-height: 10vh;" onclick="loadPoints()">Load points from file</button> + + <p id="savePoints" style="display: none; margin-top: 2vh;">Save points to file</p><br> + <input id="fileName" style="display: none;"><br> + <button id="save" class="onClick" style="display: none; margin-top: 2vh;" onclick="saveToFile()">Save</button> + + <button id="removePoints" class="onClick" style="margin-top: 2vh; line-height: 10vh; display: none;" onclick="handleDefaultPoints()">Remove current points</button> + </div> + + <div id="makeNewPointBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Make new point</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('makeNewPointBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> + + <p>Lengdegrader: <input id="lengdegrader" readonly></p> <!-- 10.xxx --> + <p>Breddegrader: <input id="breddegrader" readonly></p> <!-- 6x.xxx --> + + <p>Set category: <input id="pointCategory"></p> + <p>Set name: <input id="pointName"></p> + + <button id="savePoint" class="onClick" style="margin-top: 2vh;" onclick="savePoint()">Save point</button> + </div> </div> <div class="box2"> @@ -279,11 +321,21 @@ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3v-3z"/> </svg> + <svg id="pointOpener" style="cursor: pointer; border: none; position: absolute; color: orangered; z-index: 999; display: none;" onclick="openBox('loadPointsBox');" + xmlns="http://www.w3.org/2000/svg" width="6vh" height="6vh" fill="currentColor" class="bi bi-plus-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3v-3z"/> + </svg> + <svg id="mapChanger" style="margin-left: 8vh; cursor: pointer; border: none; position: absolute; color: orangered; z-index: 999;" onclick="changeMap()" xmlns="http://www.w3.org/2000/svg" width="6vh" height="6vh" fill="currentColor" class="bi bi-pin-map-fill" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M3.1 11.2a.5.5 0 0 1 .4-.2H6a.5.5 0 0 1 0 1H3.75L1.5 15h13l-2.25-3H10a.5.5 0 0 1 0-1h2.5a.5.5 0 0 1 .4.2l3 4a.5.5 0 0 1-.4.8H.5a.5.5 0 0 1-.4-.8l3-4z"/> <path fill-rule="evenodd" d="M4 4a4 4 0 1 1 4.5 3.969V13.5a.5.5 0 0 1-1 0V7.97A4 4 0 0 1 4 3.999z"/> </svg> + + <svg id="addPointButton" style="margin-left: 16vh; cursor: pointer; border: none; position: absolute; color: orangered; z-index: 999; display: none;" onclick="addPoint(), event.stopPropagation()" + xmlns="http://www.w3.org/2000/svg" width="6vh" height="6vh" fill="currentColor" class="bi bi-geo" viewBox="0 0 16 16"> + <path fill-rule="evenodd" d="M8 1a3 3 0 1 0 0 6 3 3 0 0 0 0-6M4 4a4 4 0 1 1 4.5 3.969V13.5a.5.5 0 0 1-1 0V7.97A4 4 0 0 1 4 3.999zm2.493 8.574a.5.5 0 0 1-.411.575c-.712.118-1.28.295-1.655.493a1.319 1.319 0 0 0-.37.265.301.301 0 0 0-.057.09V14l.002.008a.147.147 0 0 0 .016.033.617.617 0 0 0 .145.15c.165.13.435.27.813.395.751.25 1.82.414 3.024.414s2.273-.163 3.024-.414c.378-.126.648-.265.813-.395a.619.619 0 0 0 .146-.15.148.148 0 0 0 .015-.033L12 14v-.004a.301.301 0 0 0-.057-.09 1.318 1.318 0 0 0-.37-.264c-.376-.198-.943-.375-1.655-.493a.5.5 0 1 1 .164-.986c.77.127 1.452.328 1.957.594C12.5 13 13 13.4 13 14c0 .426-.26.752-.544.977-.29.228-.68.413-1.116.558-.878.293-2.059.465-3.34.465-1.281 0-2.462-.172-3.34-.465-.436-.145-.826-.33-1.116-.558C3.26 14.752 3 14.426 3 14c0-.599.5-1 .961-1.243.505-.266 1.187-.467 1.957-.594a.5.5 0 0 1 .575.411"/> + </svg> </div> <div style="width: 95vw;"></div> @@ -301,6 +353,12 @@ <!-- Leaflet js --> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> + <!-- Saving files --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script> + + <!-- Heatmap --> + <script src="javascript/leaflet-heat.js"></script> + <!-- My js --> <!-- General --> @@ -327,8 +385,10 @@ <!-- Map change --> <script src="javascript/mapChange.js"></script> + <script src="javascript/pointMap.js"></script> <script src="javascript/voronoi.js"></script> <script src="javascript/tin.js"></script> + <script src="javascript/heatmap.js"></script> </body> </html> diff --git a/javascript/exampleData/points.geojson b/javascript/exampleData/points.geojson new file mode 100644 index 0000000..799c45c --- /dev/null +++ b/javascript/exampleData/points.geojson @@ -0,0 +1,35 @@ +{ +"type": "FeatureCollection", +"features": [ +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4044907, 63.4173049]}, "properties": {"category": "Universitet", "name": "NTNU Gløshaugen"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4696324, 63.4079572]}, "properties": {"category": "Universitet", "name": "NTNU Dragvoll"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.388918, 63.4203714]}, "properties": {"category": "Universitet", "name": "NTNU Øya"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4347967, 63.4235678]}, "properties": {"category": "Universitet", "name": "NTNU Tyholt"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4143153, 63.433756]}, "properties": {"category": "Universitet", "name": "NTNU Solsiden"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4336351, 63.4138729]}, "properties": {"category": "Universitet", "name": "NTNU Moholt"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4032871, 63.4340888]}, "properties": {"category": "Universitet", "name": "NTNU Olavskvartalet"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4071882, 63.4107064]}, "properties": {"category": "Universitet", "name": "NTNU Lerkendal og Valgrinda"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3861107, 63.4288662]}, "properties": {"category": "Universitet", "name": "NTNU Kalvskinnet"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4540302, 63.4473022]}, "properties": {"category": "Universitet", "name": "NTNU Ringve"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3483128, 63.4415347]}, "properties": {"category": "Universitet", "name": "NTNU Heggdalen"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4492127, 63.4521411]}, "properties": {"category": "Universitet", "name": "NTNU Østmarka"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3981586, 63.4373727]}, "properties": {"category": "Universitet", "name": "NTNU Brattørkaia"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3992594, 63.4152944]}, "properties": {"category": "Universitet", "name": "NTNU Elgeseter"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4837531, 63.4393659]}, "properties": {"category": "Universitet", "name": "NTNU Rotvoll"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4660445, 63.42338]}, "properties": {"category": "Universitet", "name": "NTNU Tunga"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4176387, 63.4141732]}, "properties": {"category": "Studentby", "name": "Berg Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4301549, 63.4110984]}, "properties": {"category": "Studentby", "name": "Moholt Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4372857, 63.3989126]}, "properties": {"category": "Studentby", "name": "Steinan Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3918823, 63.420511]}, "properties": {"category": "Studentby", "name": "Bloksberg Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4382451, 63.4116778]}, "properties": {"category": "Studentby", "name": "Karinelund Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4945864, 63.4211031]}, "properties": {"category": "Studentby", "name": "Jakobsliveien 55"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.396918, 63.4226982]}, "properties": {"category": "Studentby", "name": "Klostergata 18"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3963873, 63.4227505]}, "properties": {"category": "Studentby", "name": "Klostergata 20"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3891634, 63.4232409]}, "properties": {"category": "Studentby", "name": "Klostergata 56"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4126211, 63.4147073]}, "properties": {"category": "Studentby", "name": "Nedre Berg Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3973319, 63.418334]}, "properties": {"category": "Studentby", "name": "Magnus den godes gate 2"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4037983, 63.4215247]}, "properties": {"category": "Studentby", "name": "Nedre Singsakerslette"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3890993, 63.4276236]}, "properties": {"category": "Studentby", "name": "Sverresgate 8"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4122453, 63.4337663]}, "properties": {"category": "Studentby", "name": "Nedre elvehavn Studentby"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3982518, 63.4163341]}, "properties": {"category": "Studentby", "name": "Teknobyen Studentboliger"}}, +{"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4003657, 63.4117822]}, "properties": {"category": "Studentby", "name": "Lerkendal Studentby"}}]} \ No newline at end of file diff --git a/javascript/heatmap.js b/javascript/heatmap.js new file mode 100644 index 0000000..4fec200 --- /dev/null +++ b/javascript/heatmap.js @@ -0,0 +1,28 @@ +var isHeat = false; + +var intensity = 100; +var heat = null; + +function heatmap() { + if (points != null) { + if (isHeat && heat != null) { + map.removeLayer(heat); + isHeat = false; + } else { + var data = getPoints(); + heat = L.heatLayer(data); + isHeat = true; + heat.addTo(map); + } + } +} + +function getPoints() { + var data = points.toGeoJSON().features; + var heatData = []; + for (point in data) { + heatData.push([data[point].geometry.coordinates[1], data[point].geometry.coordinates[0], intensity]); + } + + return heatData; +} diff --git a/javascript/leaflet-heat.js b/javascript/leaflet-heat.js new file mode 100644 index 0000000..aa8031a --- /dev/null +++ b/javascript/leaflet-heat.js @@ -0,0 +1,11 @@ +/* + (c) 2014, Vladimir Agafonkin + simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas + https://github.com/mourner/simpleheat +*/ +!function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t,i){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/* + (c) 2014, Vladimir Agafonkin + Leaflet.heat, a tiny and fast heatmap plugin for Leaflet. + https://github.com/Leaflet/Leaflet.heat +*/ +L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=L.DomUtil.testProp(["transformOrigin","WebkitTransformOrigin","msTransformOrigin"]);t.style[i]="50% 50%";var a=this._map.getSize();t.width=a.x,t.height=a.y;var s=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(s?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,d=[],_=this._heat._r,l=this._map.getSize(),m=new L.Bounds(L.point([-_,-_]),l.add([_,_])),c=void 0===this.options.max?1:this.options.max,u=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,f=1/Math.pow(2,Math.max(0,Math.min(u-this._map.getZoom(),12))),g=_/2,p=[],v=this._map._getMapPanePos(),w=v.x%g,y=v.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(a=this._map.latLngToContainerPoint(this._latlngs[t]),m.contains(a)){e=Math.floor((a.x-w)/g)+2,n=Math.floor((a.y-y)/g)+2;var x=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=x*f,p[n]=p[n]||[],s=p[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):p[n][e]=[a.x,a.y,r]}for(t=0,i=p.length;i>t;t++)if(p[t])for(h=0,o=p[t].length;o>h;h++)s=p[t][h],s&&d.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],c)]);this._heat.data(d).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t,i){return new L.HeatLayer(t,i)}; \ No newline at end of file diff --git a/javascript/mapChange.js b/javascript/mapChange.js index 562947f..7434bec 100644 --- a/javascript/mapChange.js +++ b/javascript/mapChange.js @@ -1,50 +1,8 @@ // Variabler: -// Punktene brukt i visningen av "kart 2": -var points = { - "type": "FeatureCollection", - "features": [ - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4044907, 63.4173049]}, "properties": {"category": "Universitet", "name": "NTNU Gløshaugen"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4696324, 63.4079572]}, "properties": {"category": "Universitet", "name": "NTNU Dragvoll"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.388918, 63.4203714]}, "properties": {"category": "Universitet", "name": "NTNU Øya"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4347967, 63.4235678]}, "properties": {"category": "Universitet", "name": "NTNU Tyholt"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4143153, 63.433756]}, "properties": {"category": "Universitet", "name": "NTNU Solsiden"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4336351, 63.4138729]}, "properties": {"category": "Universitet", "name": "NTNU Moholt"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4032871, 63.4340888]}, "properties": {"category": "Universitet", "name": "NTNU Olavskvartalet"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4071882, 63.4107064]}, "properties": {"category": "Universitet", "name": "NTNU Lerkendal og Valgrinda"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3861107, 63.4288662]}, "properties": {"category": "Universitet", "name": "NTNU Kalvskinnet"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4540302, 63.4473022]}, "properties": {"category": "Universitet", "name": "NTNU Ringve"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3483128, 63.4415347]}, "properties": {"category": "Universitet", "name": "NTNU Heggdalen"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4492127, 63.4521411]}, "properties": {"category": "Universitet", "name": "NTNU Østmarka"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3981586, 63.4373727]}, "properties": {"category": "Universitet", "name": "NTNU Brattørkaia"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3992594, 63.4152944]}, "properties": {"category": "Universitet", "name": "NTNU Elgeseter"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4837531, 63.4393659]}, "properties": {"category": "Universitet", "name": "NTNU Rotvoll"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4660445, 63.42338]}, "properties": {"category": "Universitet", "name": "NTNU Tunga"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4176387, 63.4141732]}, "properties": {"category": "Studentby", "name": "Berg Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4301549, 63.4110984]}, "properties": {"category": "Studentby", "name": "Moholt Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4372857, 63.3989126]}, "properties": {"category": "Studentby", "name": "Steinan Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3918823, 63.420511]}, "properties": {"category": "Studentby", "name": "Bloksberg Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4382451, 63.4116778]}, "properties": {"category": "Studentby", "name": "Karinelund Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4945864, 63.4211031]}, "properties": {"category": "Studentby", "name": "Jakobsliveien 55"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.396918, 63.4226982]}, "properties": {"category": "Studentby", "name": "Klostergata 18"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3963873, 63.4227505]}, "properties": {"category": "Studentby", "name": "Klostergata 20"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3891634, 63.4232409]}, "properties": {"category": "Studentby", "name": "Klostergata 56"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4126211, 63.4147073]}, "properties": {"category": "Studentby", "name": "Nedre Berg Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3973319, 63.418334]}, "properties": {"category": "Studentby", "name": "Magnus den godes gate 2"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4037983, 63.4215247]}, "properties": {"category": "Studentby", "name": "Nedre Singsakerslette"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3890993, 63.4276236]}, "properties": {"category": "Studentby", "name": "Sverresgate 8"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4122453, 63.4337663]}, "properties": {"category": "Studentby", "name": "Nedre elvehavn Studentby"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3982518, 63.4163341]}, "properties": {"category": "Studentby", "name": "Teknobyen Studentboliger"}}, - {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4003657, 63.4117822]}, "properties": {"category": "Studentby", "name": "Lerkendal Studentby"}} - ] -}; - var m = "m1"; // Hvilket kart en bruker var layersOnMap = []; // Hvilke kartlag som var på i "m1" før en byttet til "m2" -// Legger til alle punktene over og setter på en popup med info-tekst: -var NTNU_points = L.geoJSON(points).bindPopup(function(point) {return "<b>" + point.feature.properties.category + "</b>" + "<br>" + point.feature.properties.name;}) - // Bytter layout på nettsiden ved kartbytte function changeMap() { @@ -66,8 +24,9 @@ function changeMap() { // Endrer knappene nedrest til høyre i kartet: document.getElementById("sidebarOpener").style.display = "none"; - document.getElementById("mapChanger").style.marginLeft = "0"; - + document.getElementById("pointOpener").style.display = "block"; + document.getElementById("addPointButton").style.display = "block"; + // Skjuler synlige kartlag i kartet: for (key in overlayMaps) { var layer = overlayMaps[key]; @@ -76,9 +35,6 @@ function changeMap() { layersOnMap.push(key); } } - - // Legger til nye punkt-markører i kartet: - NTNU_points.addTo(map); } else if (m == "m2") { m = "m1"; @@ -88,18 +44,25 @@ function changeMap() { // Endrer knappene nedrest til høyre i kartet: document.getElementById("sidebarOpener").style.display = "block"; - document.getElementById("mapChanger").style.marginLeft = "8vh"; + document.getElementById("pointOpener").style.display = "none"; + document.getElementById("addPointButton").style.display = "none"; // Fjerner punkt-markørene og eventuelle voronoi- og TIN-diagram fra kartet: - if (map.hasLayer(NTNU_points)) { - map.removeLayer(NTNU_points); - } if (isVoronoi) { - voronoi(); + voronoi(); } if (isTIN) { TIN(); } + if (isHeat) { + heatmap(); + } + + if (points != null) { + if (map.hasLayer(points)) { + handleDefaultPoints(); + } + } // Legger til kartlagene som lå i kartet før en byttet kartmodus: while (layersOnMap.length > 0) { diff --git a/javascript/pointMap.js b/javascript/pointMap.js new file mode 100644 index 0000000..6e50849 --- /dev/null +++ b/javascript/pointMap.js @@ -0,0 +1,218 @@ +// Punktene brukt i visningen av "kart 2": +/* +var NTNU_points = { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4044907, 63.4173049]}, "properties": {"category": "Universitet", "name": "NTNU Gløshaugen"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4696324, 63.4079572]}, "properties": {"category": "Universitet", "name": "NTNU Dragvoll"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.388918, 63.4203714]}, "properties": {"category": "Universitet", "name": "NTNU Øya"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4347967, 63.4235678]}, "properties": {"category": "Universitet", "name": "NTNU Tyholt"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4143153, 63.433756]}, "properties": {"category": "Universitet", "name": "NTNU Solsiden"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4336351, 63.4138729]}, "properties": {"category": "Universitet", "name": "NTNU Moholt"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4032871, 63.4340888]}, "properties": {"category": "Universitet", "name": "NTNU Olavskvartalet"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4071882, 63.4107064]}, "properties": {"category": "Universitet", "name": "NTNU Lerkendal og Valgrinda"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3861107, 63.4288662]}, "properties": {"category": "Universitet", "name": "NTNU Kalvskinnet"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4540302, 63.4473022]}, "properties": {"category": "Universitet", "name": "NTNU Ringve"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3483128, 63.4415347]}, "properties": {"category": "Universitet", "name": "NTNU Heggdalen"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4492127, 63.4521411]}, "properties": {"category": "Universitet", "name": "NTNU Østmarka"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3981586, 63.4373727]}, "properties": {"category": "Universitet", "name": "NTNU Brattørkaia"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3992594, 63.4152944]}, "properties": {"category": "Universitet", "name": "NTNU Elgeseter"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4837531, 63.4393659]}, "properties": {"category": "Universitet", "name": "NTNU Rotvoll"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4660445, 63.42338]}, "properties": {"category": "Universitet", "name": "NTNU Tunga"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4176387, 63.4141732]}, "properties": {"category": "Studentby", "name": "Berg Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4301549, 63.4110984]}, "properties": {"category": "Studentby", "name": "Moholt Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4372857, 63.3989126]}, "properties": {"category": "Studentby", "name": "Steinan Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3918823, 63.420511]}, "properties": {"category": "Studentby", "name": "Bloksberg Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4382451, 63.4116778]}, "properties": {"category": "Studentby", "name": "Karinelund Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4945864, 63.4211031]}, "properties": {"category": "Studentby", "name": "Jakobsliveien 55"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.396918, 63.4226982]}, "properties": {"category": "Studentby", "name": "Klostergata 18"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3963873, 63.4227505]}, "properties": {"category": "Studentby", "name": "Klostergata 20"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3891634, 63.4232409]}, "properties": {"category": "Studentby", "name": "Klostergata 56"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4126211, 63.4147073]}, "properties": {"category": "Studentby", "name": "Nedre Berg Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3973319, 63.418334]}, "properties": {"category": "Studentby", "name": "Magnus den godes gate 2"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4037983, 63.4215247]}, "properties": {"category": "Studentby", "name": "Nedre Singsakerslette"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3890993, 63.4276236]}, "properties": {"category": "Studentby", "name": "Sverresgate 8"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4122453, 63.4337663]}, "properties": {"category": "Studentby", "name": "Nedre elvehavn Studentby"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.3982518, 63.4163341]}, "properties": {"category": "Studentby", "name": "Teknobyen Studentboliger"}}, + {"type": "Feature", "geometry": {"type": "Point", "coordinates": [10.4003657, 63.4117822]}, "properties": {"category": "Studentby", "name": "Lerkendal Studentby"}} + ] +}; +*/ + +// Initialiserer punkt-laget: +var points = null; + +var newPoint = false; + +map.addEventListener('click', (event) => { + if (newPoint) { + onMapClick(event); + } +}) + +function addPoint() { + document.getElementById("addPointButton").style.color = "green"; + newPoint = true; + + if (isTIN) { + TIN(); + } + if (isVoronoi) { + voronoi(); + } +} + +function onMapClick(e) { + openBox("makeNewPointBox"); + document.getElementById("lengdegrader").value = e.latlng.lng; + document.getElementById("breddegrader").value = e.latlng.lat; + + document.getElementById("addPointButton").style.color = "orangered"; + newPoint = false; +} + +function savePoint() { + var regex = /^[a-zA-Z_0-9]+$/; + + if (document.getElementById("pointCategory").value == "") { + return alert("You need to choose a category!"); + } else if (!document.getElementById("pointCategory").value.match(regex)) { + return alert("The category must consist of normal letters!"); + } else if (document.getElementById("pointName").value == "") { + return alert("You need to choose a name!"); + } else if (!document.getElementById("pointName").value.match(regex)) { + return alert("The name must consist of normal letters!"); + } + + var lon = document.getElementById("lengdegrader").value; + var lat = document.getElementById("breddegrader").value; + var category = document.getElementById("pointCategory").value; + var name = document.getElementById("pointName").value; + + if (points == null) { + var content = {"type": "FeatureCollection", "features": []} + var newPoint = {"type": "Feature", "geometry": {"type": "Point", "coordinates": [lon, lat]}, "properties": {"category": category, "name": name}}; + content.features.push(newPoint); + points = L.geoJSON(content).bindPopup(function(point) {return "<b>" + point.feature.properties.category + "</b>" + "<br>" + point.feature.properties.name}); + points.addTo(map); + pointsExists(); + } else { + var newPoint = {"type": "Feature", "geometry": {"type": "Point", "coordinates": [lon, lat]}, "properties": {"category": category, "name": name}}; + var content = points.toGeoJSON(); + content.features.push(newPoint); + map.removeLayer(points); + points = L.geoJSON(content).bindPopup(function(point) {return "<b>" + point.feature.properties.category + "</b>" + "<br>" + point.feature.properties.name}); + points.addTo(map); + } + + document.getElementById("pointCategory").value = ""; + document.getElementById("pointName").value = ""; + closeBox("makeNewPointBox"); +} + +function handleDefaultPoints() { + if (points != null) { + if (map.hasLayer(points)){ + document.getElementById("examplePoints").style.display = "inline-block"; + document.getElementById("loadPoints").style. display = "inline-block"; + document.getElementById("savePoints").style.display = "none"; + document.getElementById("fileName").style.display = "none"; + document.getElementById("save").style.display = "none"; + document.getElementById("removePoints").style.display = "none"; + + if (isVoronoi) { + voronoi(); + } + if (isTIN) { + TIN(); + } + if (isHeat) { + heatmap(); + } + + // Fjerner punktene: + map.removeLayer(points); + points = null; + + closeBox('loadPointsBox') + } + } else { + pointsExists(); + + // Legger til alle punktene fra default-fila og setter på en popup med info-tekst: + + + fetch("javascript/exampleData/points.geojson").then(function(response) { + return response.json(); + }).then(function(data) { + points.addData(data).bindPopup(function(point) {return "<b>" + point.feature.properties.category + "</b>" + "<br>" + point.feature.properties.name}); + }) + + + //points = L.geoJSON(NTNU_points).bindPopup(function(point) {return `<b>${point.feature.properties.category}</b><br>${point.feature.properties.name}`}); + + // Legger til nye punkt-markører i kartet: + points.addTo(map); + + closeBox('loadPointsBox') + } +} + +function loadPoints() { + document.getElementById("fileInput2").click(); +} + +document.getElementById("fileInput2").addEventListener("change", () => { + var selectedFile = document.getElementById("fileInput2").files[0]; + + if (selectedFile != null) { + document.getElementById("fileInput2").value = ""; + + var read = new FileReader(); + read.readAsDataURL(selectedFile); + + var newLayer = L.geoJSON(); + + read.onloadend = function() { + fetch(read.result).then(function(response) { + return response.json(); + }).then(function(data) { + newLayer.addData(data).bindPopup(function(point) {return "<b>" + point.feature.properties.category + "</b>" + "<br>" + point.feature.properties.name}); + }) + } + } + + points = newLayer; + points.addTo(map); + + pointsExists(); + closeBox('loadPointsBox'); +}) + +function pointsExists() { + document.getElementById("examplePoints").style.display = "none"; + document.getElementById("loadPoints").style. display = "none"; + document.getElementById("savePoints").style.display = "inline-block"; + document.getElementById("fileName").style.display = "inline-block"; + document.getElementById("save").style.display = "inline-block"; + document.getElementById("removePoints").style.display = "inline-block"; +} + +function saveToFile() { + var regex = /^[a-zA-Z_0-9]+$/; + + if (document.getElementById("fileName").value == "") { + return alert("You need to choose a name!"); + } else if (!document.getElementById("fileName").value.match(regex)) { + return alert("The category must consist of normal letters!"); + } + + var geoJSON = points.toGeoJSON(); + var fileName = document.getElementById("fileName").value; + var file = fileName + ".geojson"; + saveAs(new File([JSON.stringify(geoJSON)], file, { + type: "text/plain;charset=utf-8" + }), file); + + document.getElementById("fileName").value = ""; +} diff --git a/javascript/tin.js b/javascript/tin.js index fef7d85..26f2386 100644 --- a/javascript/tin.js +++ b/javascript/tin.js @@ -2,17 +2,22 @@ var isTIN = false // Vises TIN'et i kartet? -// Selve TIN'et: -var TINPolygons = turf.tin(NTNU_points.toGeoJSON()); -var TINGeoJSON = L.geoJSON(TINPolygons, {style: {"color": "orangered"}}); +var TINPolygons = null; +var TINGeoJSON = null; // Funksjon for å slå av og på TIN'et: function TIN() { - if (isTIN) { - map.removeLayer(TINGeoJSON); - isTIN = false; - } else { - TINGeoJSON.addTo(map); - isTIN = true; + if (points != null) { + if (isTIN && TINGeoJSON != null) { + map.removeLayer(TINGeoJSON); + isTIN = false; + } else { + // Selve TIN'et: + TINPolygons = turf.tin(points.toGeoJSON()); + TINGeoJSON = L.geoJSON(TINPolygons, {style: {"color": "orangered"}}); + + TINGeoJSON.addTo(map); + isTIN = true; + } } } diff --git a/javascript/voronoi.js b/javascript/voronoi.js index 9e51de7..df39829 100644 --- a/javascript/voronoi.js +++ b/javascript/voronoi.js @@ -2,21 +2,50 @@ var isVoronoi = false; // Vises voronoi-diagrammet i kartet? -// Avgrensning for voronoi-diagrammet -var options = { - bbox: [10.3175248, 63.3911153, 10.5242766, 63.4570029] -}; - -// Selve voronoi-diagrammet: -var voronoiPolygons = turf.voronoi(NTNU_points.toGeoJSON(), options); -var voronoiGeoJSON = L.geoJSON(voronoiPolygons, {style: {"color": "orange"}}); +var voronoiPolygons = null; +var voronoiGeoJSON = null; function voronoi() { // Skrur av og på voronoi-diagrammet i kartet - if (isVoronoi) { - map.removeLayer(voronoiGeoJSON) - isVoronoi = false; - } else { - voronoiGeoJSON.addTo(map); - isVoronoi = true; + if (points != null) { + if (isVoronoi && voronoiGeoJSON != null) { + map.removeLayer(voronoiGeoJSON) + isVoronoi = false; + } else { + + // Avgrensning for voronoi-diagrammet + + var [minlon, minlat, maxlon, maxlat] = findMinMax(); + + var options = { + bbox: [minlon, minlat, maxlon, maxlat] + }; + + // Selve voronoi-diagrammet: + voronoiPolygons = turf.voronoi(points.toGeoJSON(), options); + voronoiGeoJSON = L.geoJSON(voronoiPolygons, {style: {"color": "orange"}}); + + voronoiGeoJSON.addTo(map); + isVoronoi = true; + } + } +} + +function findMinMax() { + var [minlon, minlat, maxlon, maxlat] = [99, 99, -99, -99]; + + for (feature in points.toGeoJSON().features) { + if (points.toGeoJSON().features[feature].geometry.coordinates[0] < minlon) { + minlon = points.toGeoJSON().features[feature].geometry.coordinates[0]; + } + if (points.toGeoJSON().features[feature].geometry.coordinates[0] > maxlon) { + maxlon = points.toGeoJSON().features[feature].geometry.coordinates[0]; + } + if (points.toGeoJSON().features[feature].geometry.coordinates[1] < minlat) { + minlat = points.toGeoJSON().features[feature].geometry.coordinates[1]; + } + if (points.toGeoJSON().features[feature].geometry.coordinates[1] > maxlat) { + maxlat = points.toGeoJSON().features[feature].geometry.coordinates[1]; + } } + return [minlon - 0.5, minlat - 0.5, maxlon + 0.5, maxlat + 0.5]; } -- GitLab