var IndexViewModel = function(model) {
var self = this,
_map,
_featureNameMarkers = [],
_mouseTools = {},
_$textMeasurer = $("#text-measurer"),
_hAlign = { left: 0, center: 1, right: 2 },
_vAlign = { top: 0, middle: 1, bottom: 2 };
// ******************************** Knockout observables ********************************
self.zoom = ko.observable(model.zoom);
self.showFeatureNames = ko.observable(model.featureNames);
self.showFeatureNames.subscribe(function(newValue) {
if(newValue) {
loadFeatureNames(true);
loadWFSLayers();
} else {
clearFeatureNames();
clearWFSLayers();
}
});
self.contextMenu = {
visible: ko.observable(false),
top: ko.observable(),
left: ko.observable(),
lat: ko.observable(),
lng: ko.observable()
};
self.contextMenu.getLinkToKSO = function() {
var wgs84 = {
lat: self.contextMenu.lat(),
lng: self.contextMenu.lng()
};
var sweref99 = GeoUtil.wgs84ToSweref99(wgs84);
return "https://kso.etjanster.lantmateriet.se/?e=" + sweref99.x + "&n=" + sweref99.y + "&z=11&profile=default_orto_noauth";
};
self.contextMenu.getLinkToSGU = function() {
var wgs84 = {
lat: self.contextMenu.lat(),
lng: self.contextMenu.lng()
};
var sweref99 = GeoUtil.wgs84ToSweref99(wgs84);
var right = Number(sweref99.x) + 1000;
var left = Number(sweref99.x) - 1000;
var top = Number(sweref99.y) + 1000;
var bottom = Number(sweref99.y) - 1000;
return "http://apps.sgu.se/kartvisare/kartvisare-jordarter-25-100-tusen-sv.html?zoom=" + String(left) + "," + String(bottom) + "," + String(right) + "," + String(top);
};
self.contextMenu.getLinkToGoogleMaps = function() {
return "https://www.google.se/maps/@" + self.contextMenu.lat() + "," + self.contextMenu.lng() + ",2000m/data=!3m1!1e3";
};
self.contextMenu.getLinkToView = function() {
return "/?lat=" + self.contextMenu.lat() + "&lng=" + self.contextMenu.lng() + "&zoom=" + self.zoom() + (self.showFeatureNames() ? "&featureNames=true" : "");
};
self.isAdmin = model.isAdmin;
self.password = ko.observable();
self.initMap = function() {
_map = createMap();
_wfslayers = createWFSLayers(_map);
loadFeatureNames();
loadWFSLayers();
};
self.currentMouseTool = ko.observable();
self.tools = {};
self.zoomLevels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15];
// ******************************** Knockout event handlers ********************************
self.onLoginButtonClicked = function() {
var request = {
password: self.password()
};
$.postJson("/ajax/login.php", request)
.done(function(response) {
window.location.replace("//www.mapant.fi");
})
.fail(function(jqXhr) {
});
};
self.contextMenu.onRecreateTileLinkClicked = function() {
var wgs84 = {
lat: self.contextMenu.lat(),
lng: self.contextMenu.lng()
};
var request = {
latitude: wgs84.lat,
longitude: wgs84.lng,
full: false
};
$.postJson("/ajax/recreateTile.php", request);
self.contextMenu.visible(false);
};
self.contextMenu.onRecreateTileFullLinkClicked = function() {
var wgs84 = {
lat: self.contextMenu.lat(),
lng: self.contextMenu.lng()
};
var sweref99 = GeoUtil.wgs84ToSweref99(wgs84);
var request = {
latitude: wgs84.lat,
longitude: wgs84.lng,
full: true
};
$.postJson("/ajax/recreateTile.php", request);
self.contextMenu.visible(false);
};
self.onFeatureNameButtonClicked = function() {
self.showFeatureNames(!self.showFeatureNames());
};
// ******************************** functions ********************************
function createMap(){
var crs = new L.Proj.CRS.TMS('EPSG:3067',
'+proj=utm +zone=35 +ellps=GRS80 +units=m +towgs84=0,0,0,-0,-0,-0,0 +no_defs',
[-548576.0, 6291456.0, 1548576.0, 8388608],
{
resolutions: [
8192,
4096,
2048,
1024,
512,
256,
128,
64,
32,
16,
8,
4,
2,
1,
0.5,
0.25
]
});
var map = new L.Map('map', {
crs: crs,
continuousWorld: true,
worldCopyJump: false,
zoomControl: true
});
var templateUrl = '//wmts.mapant.fi/wmts.php?v=2&z={z}&x={x}&y={y}';
new L.TileLayer(templateUrl, {
maxZoom: 15,
minZoom: 0,
continuousWorld: true,
attribution: 'Laser scanning and topographic data provided by the National Land Survey of Finland under the Creative Commons license.'
}).addTo(map);
new L.control.scale({
position: 'bottomright',
imperial: false
}).addTo(map);
if(model.lat && model.lng) {
map.setView([model.lat, model.lng], model.zoom);
} else {
map.setView(new L.LatLng(62,25),3);
/*
map.locate({
setView: true,
maxZoom: 7
});
*/
}
L.Control.measureControl().addTo(map);
L.geoJson(finlandBorder, {
style: {
weight: 4,
color: "#00e6b8",
opacity: 1
}
}).addTo(map);
// setup event handlers
map.on("zoomstart", onMapZoomStart);
map.on("zoomend", onMapZoomEnd);
map.on("movestart", onMapMoveStart);
map.on("moveend", onMapMoveEnd);
map.on("contextmenu", onMapContextMenu, false);
map.on("mousedown", onMapMouseDown);
map.on("mouseup", onMapMouseUp);
map.on("mousemove", onMapMouseMove);
$("#map-container").on("contextmenu", function(ev) {
ev.preventDefault();
return false;
});
map.on("click", function(ev) {
self.contextMenu.visible(false);
return false;
}, false);
// Set default view if location not found or denied
map.on("locationerror", function() {
map.setView(new L.LatLng(62,25),0);
});
return map;
}
function createWFSLayers(_map) {
// Layers created in wfslayers.js
return [ create_naturreservat(_map),
create_nationalpark(_map),
create_vag_planerad(_map),
create_vag_framtida(_map),
create_jarnvag_planerad(_map),
create_jarnvag_framtida(_map),
create_naturskydd_framtida(_map)];
}
function loadWFSLayers() {
if(!self.showFeatureNames()) {
return;
}
_wfslayers.forEach(function(layer) {
layer.setMap(_map);
});
}
function clearWFSLayers() {
_wfslayers.forEach(function(layer) {
layer.setMap(null);
});
}
function loadFeatureNames(clear) {
if(!self.showFeatureNames()) {
clearFeatureNames();
return;
}
if(self.zoom() < 10) {
// too small scale, don't output names for now
clearFeatureNames();
return;
}
// 1. get bounds
var bounds = _map.getBounds();
// 2. translate to SWEREF
var nw = bounds.getNorthWest(),
sw = bounds.getSouthWest(),
se = bounds.getSouthEast(),
ne = bounds.getNorthEast();
// 3. fetch names
var request = {
south: Math.min(sw.lat, se.lat),
north: Math.max(nw.lat, ne.lat),
west: Math.min(sw.lng, nw.lng),
east: Math.max(se.lng, ne.lng)
};
$.postJson("/ajax/getFeatureNames.php", request)
.done(function(response) {
var featureNames = $.map(response.featureNames, function(fn) {
return {
id: parseInt(fn.id),
lat: parseFloat(fn.lat),
lng: parseFloat(fn.lng),
text: fn.text,
anchor: 1,
rotation: parseFloat(fn.rotation),
letterSpacing: null,
type: parseInt(fn.type),
size: parseInt(fn.size)
};
});
// 4. update view model
clearFeatureNames();
addFeatureNames(featureNames, clear);
})
.fail(function(jqXhr) {
});
}
function clearFeatureNames() {
$.each(_featureNameMarkers, function(i, fnm) {
_map.removeLayer(fnm);
});
_featureNameMarkers = [];
}
function addFeatureNames(featureNames, clear) {
if(clear) {
clearFeatureNames();
}
$.each(featureNames, function(i, fn) {
var di = L.divIcon({
className: "feature-name feature-name-type-" + fn.type + " feature-name-size-" + fn.size,
html: '' + fn.text + ''
});
var marker = L.marker([fn.lat, fn.lng], { icon: di }).addTo(_map);
_featureNameMarkers.push(marker);
});
}
function getFeatureNameStyle(featureName) {
var fontSize = getFontSize(featureName.size, self.zoom()),
fontSizeString = "font-size:" + fontSize + "px;",
dx,
dy,
top,
bottom,
left,
right,
rotation = "",
hAlign = anchorToHorizontalAlign(featureName.anchor),
vAlign = anchorToVerticalAlign(featureName.anchor),
// only calculate text size if necessary
textSize = featureName.rotation || hAlign === _hAlign.center || vAlign === _vAlign.middle
? measureText(featureName.text, fontSize)
: { width: 0, height: 0 }; // dummy
if (hAlign === _hAlign.left) {
dx = -textSize.width / 2;
left = 0;
} else if (hAlign === _hAlign.center) {
dx = 0;
left = -textSize.width / 2;
} else {
dx = textSize.width / 2;
right = 0;
}
if (vAlign === _vAlign.bottom) {
dy = textSize.height / 2;
bottom = 0;
} else if (vAlign === _vAlign.middle) {
dy = 0;
top = -textSize.height / 2;
} else {
dy = -textSize.height / 2;
top = 0;
}
if(featureName.rotation) {
var a1 = dy === 0 && dx === 0 ? 0 : Math.atan2(dy, dx),
a2 = a1 - featureName.rotation * Math.PI / 180,
d = Math.sqrt(dx*dx + dy*dy),
px = d * Math.cos(a2),
py = d * Math.sin(a2);
if(left !== undefined) {
left = left + (dx - px);
} else {
right = right - (dx - px);
}
if(top !== undefined) {
top = top + (dy - py);
} else {
bottom = bottom - (dy - py);
}
rotation = "transform:rotate(-" + featureName.rotation + "deg);";
}
var horizontal = left !== undefined
? "left:" + left + "px;"
: "right:" + right + "px;",
vertical = top !== undefined
? "top:" + top + "px;"
: "bottom:" + bottom + "px;";
var letterSpacing = featureName.letterSpacing
? "letter-spacing:" + (featureName.letterSpacing / 100 * fontSize) + "px;"
: "";
return fontSizeString + horizontal + vertical + rotation + letterSpacing;
}
function anchorToHorizontalAlign(anchor) {
if(anchor === 1 || anchor === 4 || anchor === 7) {
return _hAlign.left;
} else if (anchor === 2 || anchor === 5 || anchor === 8) {
return _hAlign.center;
} else {
return _hAlign.right;
}
}
function anchorToVerticalAlign(anchor) {
if (anchor === 1 || anchor === 2 || anchor === 3) {
return _vAlign.bottom;
} else if (anchor === 4 || anchor === 5 || anchor === 6) {
return _vAlign.middle;
} else {
return _vAlign.top;
}
}
function getFontSize(points, zoom) {
var baseSize = 0.4 / 19;
return baseSize * points * Math.pow(2, zoom-9);
}
function measureText(text, fontSize) {
_$textMeasurer
.text(text)
.css("font-size", fontSize + "px");
return {
width: _$textMeasurer.width(),
height: _$textMeasurer.height()
};
}
// ******************************** event handlers ********************************
function onMapZoomStart() {
clearFeatureNames();
//clearWFSLayers();
}
function onMapZoomEnd() {
self.zoom(_map._zoom);
loadFeatureNames();
//loadWFSLayers();
}
function onMapMoveStart() {
//clearWFSLayers();
}
function onMapMoveEnd() {
loadFeatureNames(true);
//loadWFSLayers();
}
function onMapContextMenu(ev) {
var x = ev.originalEvent.clientX,
y = ev.originalEvent.clientY,
cm = self.contextMenu;
cm.top(y);
cm.left(x);
cm.visible(true);
cm.lat(ev.latlng.lat.toFixed(7));
cm.lng(ev.latlng.lng.toFixed(7));
return false;
}
function onMapMouseDown(ev) {
if(_mouseTools[self.currentMouseTool()]){
_mouseTools[self.currentMouseTool()].onMouseDown(ev);
}
}
function onMapMouseUp(ev) {
if(_mouseTools[self.currentMouseTool()]){
_mouseTools[self.currentMouseTool()].onMouseUp(ev);
}
}
function onMapMouseMove(ev) {
if(_mouseTools[self.currentMouseTool()]){
_mouseTools[self.currentMouseTool()].onMouseMove(ev);
}
}
function handleMouseTool(ev) {
switch(_mouseEvent.tool) {
case "rectangle":
break;
}
}
function getExportScriptName(format) {
switch(format)
{
case "PNG": return "image.php?";
case "Georeferenced PNG": return "image.php?georeference=true";
default: return "exportKmz.php";
}
}
_mouseTools.exportMapImage = (function() {
var _mouseButtonDown,
_mouseRectangle,
_mouseDownEvent,
_mouseUpEvent,
_zoomData;
function drawRectangle(ev){
_mouseRectangle.setBounds([[_mouseDownEvent.latlng.lat, _mouseDownEvent.latlng.lng], [ev.latlng.lat, ev.latlng.lng]]);
}
function onZoomChanged(){
var vm = self.tools.exportMapImage;
var zoom = vm.zoom();
if(_zoomData) {
vm.width(_zoomData[zoom].width);
vm.height(_zoomData[zoom].height);
vm.area((_zoomData[zoom].area / 1000000).toFixed(1));
vm.tooLarge(_zoomData[zoom].tooLarge);
}
}
$("#export-map-image-modal").on("hidden.bs.modal", function () {
self.currentMouseTool(null);
});
self.tools.exportMapImage = {
onToolbarButtonClicked: function() {
self.currentMouseTool(self.currentMouseTool() === "exportMapImage" ? null : "exportMapImage");
if(self.currentMouseTool() === "exportMapImage") {
_map.dragging.disable();
}
},
onModalOkButtonClicked: function() {
var reso=map.options.crs.options.resolutions[self.tools.exportMapImage.zoom()];
var down = _mouseDownEvent.latlng,
up = _mouseUpEvent.latlng,
scriptName = getExportScriptName(self.tools.exportMapImage.format());
//getExportScriptName(self.tools.exportMapImage.format()),
// url = "//www.mapant.se/fi/" + scriptName +
// "?south=" + Math.min(down.lat, up.lat) +
// "&north=" + Math.max(down.lat, up.lat) +
// "&west=" + Math.min(down.lng, up.lng) +
// "&east=" + Math.max(down.lng, up.lng) +
// "&zoom=" + self.tools.exportMapImage.zoom();
var url = 'https://www.mapant.fi/'+ scriptName +'&west='+ Math.min(map.project(down,13).x-548576.0, map.project(up,13).x-548576.0)+'&south='+ Math.min(8388608-map.project(down,13).y,8388608- map.project(up,13).y) +'&east='+ Math.max(map.project(down,13).x-548576.0, map.project(up,13).x-548576.0)+'&north='+Math.max(8388608-map.project(down,13).y, 8388608-map.project(up,13).y)+'&width='+Math.abs(map.project(down,13).x-map.project(up,13).x)/reso+'&height='+Math.abs(map.project(down,13).y-map.project(up,13).y)/reso+'&zoom='+reso;
if (self.tools.exportMapImage.showNorthLinesCheckbox() && self.tools.exportMapImage.drawNorthLines()){
url += "&northlines=true";
}
window.location.href = url;
$("#export-map-image-modal").modal("hide");
},
zoom: ko.observable(null),
zoomInited: ko.observable(false),
format: ko.observable("PNG"),
formats: ["PNG", "Georeferenced PNG"], // , "Georeferenced PNG", "KML"
drawNorthLines: ko.observable(false),
width: ko.observable(),
height: ko.observable(),
area: ko.observable(),
tooLarge: ko.observable()
};
self.tools.exportMapImage.zoom.subscribe(onZoomChanged);
self.tools.exportMapImage.showNorthLinesCheckbox = ko.computed(function() {
return self.tools.exportMapImage.zoom() > 10;
});
var ret = {
onMouseDown: function(ev) {
if(ev.originalEvent.button === 0) {
_mouseButtonDown = true;
_mouseDownEvent = ev;
_mouseRectangle = L.rectangle([[ev.latlng.lat, ev.latlng.lng], [ev.latlng.lat, ev.latlng.lng]], {color: "#ff7800", weight: 2});
_mouseRectangle.addTo(_map);
drawRectangle(ev);
}
},
onMouseUp: function(ev) {
if(!_mouseButtonDown) {
return;
}
_mouseButtonDown = false;
_mouseUpEvent = ev;
_map.removeLayer(_mouseRectangle);
_mouseRectangle = null;
var down = _mouseDownEvent.latlng,
up = _mouseUpEvent.latlng,
request = {
south: Math.min(down.lat, up.lat),
north: Math.max(down.lat, up.lat),
west: Math.min(down.lng, up.lng),
east: Math.max(down.lng, up.lng)
};
$.postJson("/ajax/getExportMapImageSizeWMS.php", request)
.done(function(response) {
_zoomData = response;
if(!self.tools.exportMapImage.zoomInited()) {
self.tools.exportMapImage.zoom(self.zoom());
self.tools.exportMapImage.zoomInited(true);
}
onZoomChanged();
$("#export-map-image-modal").modal("show");
})
.fail(function(jqXhr) {
alert("An error occured.");
});
_map.dragging.enable();
},
onMouseMove: function(ev) {
if(_mouseButtonDown) {
drawRectangle(ev);
}
}
};
return ret;
})();
};
var viewModel;
$(function() {
window.settings = window.settings || {};
viewModel = new IndexViewModel(window.settings);
ko.applyBindings(viewModel);
if(window.settings.isAuthenticated) {
viewModel.initMap();
}
});