Commit 4122293e authored by Piotr Gawron's avatar Piotr Gawron
Browse files

OpenLayers support different layers and initial center point and zoom

parent cd304d87
......@@ -39,30 +39,38 @@
"litemol": "github:dsehnal/LiteMol#67556b0de0d2428f9494136758cbf8a662f66412"
},
"dependencies": {
"ProtVista": {
"version": "git://github.com/davidhoksza/protvista.git#4e4bb737ba1e183291505bd25f8bae2e651ce21e",
"dev": true,
"requires": {
"d3": "3.5.17",
"file-saver": "1.3.3",
"jquery": "2.2.4",
"jszip": "3.1.4",
"underscore": "1.8.3"
},
"dependencies": {
"jquery": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
"integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=",
"dev": true
}
}
},
"jquery": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==",
"dev": true
}
}
},
"ProtVista": {
"version": "git://github.com/davidhoksza/protvista.git#4e4bb737ba1e183291505bd25f8bae2e651ce21e",
"dev": true,
"requires": {
"d3": "3.5.17",
"file-saver": "1.3.3",
"jquery": "2.2.4",
"jszip": "3.1.4",
"underscore": "1.8.3"
},
"dependencies": {
"jquery": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
"integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=",
"dev": true
},
"litemol": {
"version": "github:dsehnal/LiteMol#67556b0de0d2428f9494136758cbf8a662f66412",
"dev": true,
"requires": {
"@types/react": "15.6.15",
"@types/react-dom": "15.5.7"
}
}
}
},
......@@ -3058,14 +3066,6 @@
"immediate": "3.0.6"
}
},
"litemol": {
"version": "github:dsehnal/LiteMol#67556b0de0d2428f9494136758cbf8a662f66412",
"dev": true,
"requires": {
"@types/react": "15.6.15",
"@types/react-dom": "15.5.7"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
......
......@@ -134,6 +134,11 @@ GuiConnector.prototype.getLoadingImg = function () {
return "icons/ajax-loader.gif";
};
GuiConnector.prototype.getEmptyTileUrl = function () {
return "resources/images/empty_tile.png";
};
/**
* Returns home directory for images in the application.
*/
......
......@@ -17,15 +17,6 @@ var GoogleMapsApiRectangle = require('./GoogleMapsApiRectangle');
function GoogleMapsApiCanvas(element, options) {
MapCanvas.call(this, element, options);
// following fields are used in conversion between x,y coordinates and lat,lng
// coordinates
this.pixelOrigin_ = new Point(options.tileSize / 2, options.tileSize / 2);
this.pixelsPerLonDegree_ = options.tileSize / 360;
this.pixelsPerLonRadian_ = options.tileSize / (2 * Math.PI);
/* jshint bitwise: false */
this.zoomFactor = Math.max(options.width, options.height) / (options.tileSize / (1 << options.minZoom));
var self = this;
self.setGoogleMap(new google.maps.Map(element, self.prepareGoogleMapOptions(options)));
self.setupBackgroundOverlays(options.backgroundOverlays);
......@@ -161,26 +152,6 @@ GoogleMapsApiCanvas.prototype.addCenterButton = function () {
};
/**
* Transforms coordinates on the map from {Point} to
* google.maps.LatLng
*
* @param point
* coordinates in standard x,y format
* @return coordinates in lat,lng format
*/
GoogleMapsApiCanvas.prototype.fromPointToLatLng = function (point) {
var me = this;
// rescale the point (all computations are done assuming that we work on
// TILE_SIZE square)
var p = new Point(point.x / me.zoomFactor, point.y / me.zoomFactor);
var origin = me.pixelOrigin_;
var lng = (p.x - origin.x) / me.pixelsPerLonDegree_;
var latRadians = (p.y - origin.y) / -me.pixelsPerLonRadian_;
var lat = Functions.radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2);
return new google.maps.LatLng(lat, lng);
};
/**
* Transforms google.maps.LatLng to tile coordinate (for instance on which tile
......@@ -202,33 +173,6 @@ GoogleMapsApiCanvas.prototype.latLngToTile = function (latLng, z) {
return tileCoordinate;
};
/**
* Transforms coordinates on the map from google.maps.LatLng to
* {Point}
*
* @param latLng
* in lat,lng format
* @param {Point} coordinates in x,y format
*
*/
GoogleMapsApiCanvas.prototype.fromLatLngToPoint = function (latLng) {
var me = this;
var point = new Point(0, 0);
var origin = me.pixelOrigin_;
point.x = origin.x + latLng.lng() * me.pixelsPerLonDegree_;
// Truncating to 0.9999 effectively limits latitude to 89.189. This is
// about a third of a tile past the edge of the world tile.
var siny = Functions.bound(Math.sin(Functions.degreesToRadians(latLng.lat())), -0.9999, 0.9999);
point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny)) * -me.pixelsPerLonRadian_;
// rescale the point (all computations are done assuming that we work on
// TILE_SIZE square)
point.x *= me.zoomFactor;
point.y *= me.zoomFactor;
return point;
};
GoogleMapsApiCanvas.prototype.createMarker = function (options) {
if (!(options.position instanceof Point)) {
......@@ -452,5 +396,31 @@ GoogleMapsApiCanvas.prototype.removeSelection = function () {
}
};
/**
* Transforms coordinates on the map from {Point} to
* {google.maps.LatLng}
*
* @param {Point} point
* coordinates in standard x,y format
* @return {google.maps.LatLng} coordinates in lat,lng format
*/
GoogleMapsApiCanvas.prototype.fromPointToLatLng = function (point) {
var tmp = MapCanvas.prototype.pointToLatLng.call(this, point);
return new google.maps.LatLng(tmp[0], tmp[1]);
};
/**
* Transforms coordinates on the map from {google.maps.LatLng} to
* {Point}
*
* @param {google.maps.LatLng} latLng
* in lat,lng format
* @returns {Point} coordinates in x,y format
*
*/
GoogleMapsApiCanvas.prototype.fromLatLngToPoint = function (latLng) {
return MapCanvas.prototype.latLngToPoint.call(this, [latLng.lat(), latLng.lng()]);
};
module.exports = GoogleMapsApiCanvas;
......@@ -3,7 +3,9 @@
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
var Functions = require('../../Functions');
var ObjectWithListeners = require('../../ObjectWithListeners');
var Point = require('./Point');
function MapCanvas(element, options) {
......@@ -21,6 +23,15 @@ function MapCanvas(element, options) {
this.registerListenerType("shape-rightclick");
this.setOptions(options);
// following fields are used in conversion between x,y coordinates and lat,lng
// coordinates
this.pixelOrigin_ = new Point(options.tileSize / 2, options.tileSize / 2);
this.pixelsPerLonDegree_ = options.tileSize / 360;
this.pixelsPerLonRadian_ = options.tileSize / (2 * Math.PI);
/* jshint bitwise: false */
this.zoomFactor = Math.max(options.width, options.height) / (options.tileSize / (1 << options.minZoom));
}
MapCanvas.prototype = Object.create(ObjectWithListeners.prototype);
......@@ -153,4 +164,55 @@ MapCanvas.prototype.triggerListeners = function (type, data) {
throw new Error("Not implemented");
};
/**
* Transforms coordinates on the map from {Point} to
* google.maps.LatLng
*
* @param {Point} point
* coordinates in standard x,y format
* @return {Number[]} coordinates in lat,lng format
*/
MapCanvas.prototype.pointToLatLng = function (point) {
var me = this;
// rescale the point (all computations are done assuming that we work on
// TILE_SIZE square)
var p = new Point(point.x / me.zoomFactor, point.y / me.zoomFactor);
var origin = me.pixelOrigin_;
var lng = (p.x - origin.x) / me.pixelsPerLonDegree_;
var latRadians = (p.y - origin.y) / -me.pixelsPerLonRadian_;
var lat = Functions.radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2);
return [lat, lng];
};
/**
* Transforms coordinates on the map from google.maps.LatLng to
* {Point}
*
* @param {Number[]} latLng
* in lat,lng format
* @returns {Point} coordinates in x,y format
*
*/
MapCanvas.prototype.latLngToPoint = function (latLng) {
var lat = latLng[0];
var lng = latLng[1];
var me = this;
var point = new Point(0, 0);
var origin = me.pixelOrigin_;
point.x = origin.x + lng * me.pixelsPerLonDegree_;
// Truncating to 0.9999 effectively limits latitude to 89.189. This is
// about a third of a tile past the edge of the world tile.
var siny = Functions.bound(Math.sin(Functions.degreesToRadians(lat)), -0.9999, 0.9999);
point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny)) * -me.pixelsPerLonRadian_;
// rescale the point (all computations are done assuming that we work on
// TILE_SIZE square)
point.x *= me.zoomFactor;
point.y *= me.zoomFactor;
return point;
};
module.exports = MapCanvas;
......@@ -5,6 +5,7 @@ var ol;
var logger = require('../../../logger');
var Bounds = require('../Bounds');
var GuiConnector = require('../../../GuiConnector');
var Functions = require('../../../Functions');
var MapCanvas = require('../MapCanvas');
var Point = require('../Point');
......@@ -13,19 +14,19 @@ function OpenLayerCanvas(element, options) {
ol = require('openlayers/dist/ol-debug');
MapCanvas.call(this, element, options);
$(element).css("background-color", "#e4e2de");
var self = this;
self.setOpenLayersMap(new ol.Map({
target: element,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
layers: self.createLayers(options),
view: new ol.View({
center: [0, 0],
zoom: 0
center: self.fromPointToProjection(options.center),
zoom: options.zoom,
minZoom: options.minZoom,
maxZoom: options.maxZoom
})
}));
}
OpenLayerCanvas.prototype = Object.create(MapCanvas.prototype);
......@@ -35,6 +36,57 @@ OpenLayerCanvas.prototype.setOpenLayersMap = function (map) {
this._map = map;
};
OpenLayerCanvas.prototype.createLayers = function (options) {
var self = this;
var result = [];
console.log(options);
self._layers = [];
options.backgroundOverlays.forEach(function (overlay, index) {
var layer = new ol.layer.Tile({
visible: (index === 0),
source: new ol.source.XYZ({
minZoom: options.minZoom,
maxZoom: options.maxZoom,
tileLoadFunction: function (imageTile, src) {
if (src !== null) {
imageTile.getImage().src = src;
}
},
tileUrlFunction: function (coordinate) {
var zoom = coordinate[0];
// we have 1 tile on self.getConfiguration().MIN_ZOOM and
// therefore must limit tails according to this
/* jshint bitwise: false */
var maxTileRange = 1 << (zoom - self.getMinZoom());
var maxTileXRange = maxTileRange;
var maxTileYRange = maxTileRange;
//transform the coordinates to something that was used in google maps
var x = coordinate[1];
var y = -coordinate[2] - 1;
var width = self.getWidth();
var height = self.getHeight();
if (width > height) {
maxTileYRange = height / width * maxTileRange;
} else if (width < height) {
maxTileXRange = width / height * maxTileRange;
}
if (y < 0 || y >= maxTileYRange || x < 0 || x >= maxTileXRange) {
return null;
}
return overlay.directory + "/" + zoom + "/" + x + "/" + y + ".PNG";
}
})
});
self._layers[overlay.id] = layer;
result.push(layer);
});
return result;
};
OpenLayerCanvas.prototype.setOptions = function (options) {
this._options = options;
};
......@@ -107,13 +159,30 @@ OpenLayerCanvas.prototype.setZoom = function (zoom) {
* @returns {string}
*/
OpenLayerCanvas.prototype.getBackgroundId = function () {
logger.fatal("Not implemented");
return this._backgroundId;
var layers = this._layers;
for (var id in layers) {
if (layers.hasOwnProperty(id)) {
var layer = layers[id];
if (layer.getVisible()) {
return id;
}
}
}
return null;
};
OpenLayerCanvas.prototype.setBackgroundId = function (backgroundId) {
this._backgroundId = backgroundId;
logger.fatal("Not implemented");
backgroundId = parseInt(backgroundId);
console.log("background: ", backgroundId);
var layers = this._layers;
for (var id in layers) {
if (layers.hasOwnProperty(id)) {
var layer = layers[id];
var visible = (parseInt(id) === backgroundId);
console.log(id, "show", visible);
layer.setVisible(visible);
}
}
};
/**
......@@ -161,8 +230,17 @@ OpenLayerCanvas.prototype.removeSelection = function () {
logger.fatal("Not implemented");
};
MapCanvas.prototype.triggerListeners = function (type, data) {
OpenLayerCanvas.prototype.triggerListeners = function (type, data) {
logger.fatal("Not implemented");
};
OpenLayerCanvas.prototype.fromPointToProjection = function (point) {
var latLng = this.pointToLatLng(point);
return ol.proj.fromLonLat([latLng[1], latLng[0]]);
};
OpenLayerCanvas.prototype.fromProjectionToPoint = function (projection) {
var lngLat = ol.proj.toLonLat(projection);
return this.latLngToPoint([lngLat[1], lngLat[0]]);
};
module.exports = OpenLayerCanvas;
......@@ -71,6 +71,7 @@ var google = {
this.lng = function () {
return this.longitude;
};
return this;
},
LatLngBounds: function (ne, sw) {
var data = {
......
"use strict";
require("../../../mocha-config");
// noinspection JSUnusedLocalSymbols
var logger = require('../../../logger');
var OpenLayerCanvas = require('../../../../../main/js/map/canvas/OpenLayers/OpenLayerCanvas');
var Point = require('../../../../../main/js/map/canvas/Point');
var SelectionContextMenu = require('../../../../../main/js/gui/SelectionContextMenu');
var chai = require('chai');
var assert = chai.assert;
describe('OpenLayerCanvas', function () {
var testOptions = {
center: new Point(0, 0),
tileSize: 256,
width: 300,
height: 600,
backgroundOverlays: [{
id: 1,
name: "overlay",
directory: "overlay_dir"
}]
};
it("constructor", function () {
var canvas = new OpenLayerCanvas(testDiv, testOptions);
assert.ok(canvas.pixelOrigin_);
assert.ok(canvas.pixelsPerLonDegree_);
assert.ok(canvas.pixelsPerLonRadian_);
assert.ok(canvas.zoomFactor);
});
it("Point - Projection conversion", function () {
var canvas = new OpenLayerCanvas(testDiv, testOptions);
var x = 199;
var y = 110;
var point = new Point(x, y);
var coordinates = canvas.fromPointToProjection(point);
var point2 = canvas.fromProjectionToPoint(coordinates);
assert.closeTo(point2.x, point.x, 0.5, "X coordinate is invalid after transformation");
assert.closeTo(point2.y, point.y, 0.5, "Y coordinate is invalid after transformation");
});
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment