/* (C) GeoBasis-DE/LGB
* Copyright by Landesvermessung und Geobasisinformation Brandenburg (LGB)
*
* Software engineering by Intevation GmbH
*
* This file is Free Software under the GNU GPL (>=v3)
* and comes with ABSOLUTELY NO WARRANTY! Check out the
* LICENSE for details.
*/
/**
* This controller is used to parse and evaluate URL parameters.
* The parameters currently known are:
'projection',
'layers',
'center',
*
* - kml: The URL to a kml document.
* - georss: The URL to a georss document.
* - csv: The URL to a csv document.
* - bbox: Comma separated list of coordinates (left,bottom,right,top).
* - ort, strasse, plz: Equivalent to the gazeteer search. Opens the dialog if
* multiple locations are found.
* - x, y, zoom: Set the center to x, y and zoom to the specified zoom level.
* - center: Pass the x and y coordinates as list of coordinates (x,y)
* - bglayer: Specify the background layer by ID
* - layers: Specify the layers (ID) to be displayed
* - projection: The EPSG-Code for the projection
*
* To use parameters in the base url add the controller to the controllers
* array in your app.
*
Ext.application({
classicControllers: [
'Parameter',
...
],
...
});
*
* To parse the parameters call
* {@link LGB.ext4map.controller.Parameter#evaluateParams}.
LGB.ext4map.app.getController('LGB.ext4map.controller.Parameter').evaluateParams();
*/
Ext.define('LGB.ext4map.controller.Parameter', {
extend: 'Ext.app.Controller',
requires: 'LGB.ext4map.store.LocationResult',
stores: ['LocationResult'],
/**
* The OpenLayers map object.
*/
map: null,
/**
* @private
* The parsed parameters.
*/
params: [],
/**
* @private
* The Layer to draw markers.
*/
markerLayer: null,
/**
* @private
* Layer loader instance
*/
layerLoader: null,
/**
* Set the OpenLayers map object and trigger parsing the URL parameters.
*
* @param {OpenLayers.Map} map The map object.
*/
setMap: function(map) {
this.map = map.map;
//this.markerLayer = new OpenLayers.Layer.Markers('marker');
//this.markerLayer.displayInLayerSwitcher = false;
//this.map.addLayer(this.markerLayer);
this.parseParams();
},
/**
* Parse the URL and extract the parameters.
*/
parseParams: function() {
var url = window.location;
var knownParams = ['kml',
'georss',
'csv',
'projection',
'layers',
'bglayer',
'center',
'bbox',
'ort',
'x',
'y',
'strasse',
'plz',
'zoom',
'geomaerker'];
var query = url.search.substring(1);
var qparams = query.split('&');
for (var i = qparams.length - 1; i >= 0; i--) {
var pair = qparams[i].split('=');
var key = decodeURIComponent(pair[0]);
for (var j = knownParams.length - 1; j >= 0; j--) {
if (knownParams[j] === key) {
this.params[key] = pair[1];
}
}
}
},
/**
* Evaluate the parsed parameters.
*/
evaluateParams: function() {
var me = this;
// var displayLayers = [];
// if (this.params.layers) {
// displayLayers = this.params.layers.split(',');
// console.log(displayLayers);
// }
if (this.params.zoom) {
this.map.getView().setZoom(parseInt(this.params.zoom));
}
if (this.params.layers !== undefined || this.params.bglayer){
var firstBaseLayer; // get the first baselayer as default base layer
var baseLayerDisplayed; // if there is already an baselayer defined
var layerlist = this.map.getLayers().getArray();
var displayLayers = this.params.layers ? this.params.layers.split(','): [];
for (var i = 0; i < layerlist.length; i ++ ) {
var isBaseLayer = false;
if (layerlist[i].get('options')) {
var lyrID = layerlist[i].get('options').permalinkID;
isBaseLayer = layerlist[i].get('options').isBaseLayer;
var visibleLayer = false;
if (isBaseLayer && !firstBaseLayer) {
firstBaseLayer = layerlist[i];
}
if (this.params.bglayer && this.params.bglayer == lyrID &&
isBaseLayer) {
visibleLayer = true;
baseLayerDisplayed = true;
}
if ( lyrID && displayLayers.indexOf(lyrID.toString()) != -1) {
if (isBaseLayer && !baseLayerDisplayed) {
visibleLayer = true;
baseLayerDisplayed = true;
} else if (!isBaseLayer) {
visibleLayer = true;
}
}
layerlist[i].setVisible(visibleLayer);
this.toggleLayerTree(layerlist[i], visibleLayer)
LGB.ext4map.app.fireEvent('layerstatechanged', layerlist[i]);
}
}
if (!baseLayerDisplayed) {
firstBaseLayer.setVisible(true);
this.toggleLayerTree(firstBaseLayer, true)
LGB.ext4map.app.fireEvent('layerstatechanged', firstBaseLayer);
}
}
if (this.params.projection) {
var success = this.switchProjection();
if (!success) {
return;
}
}
if (this.params.kml) {
this.createKMLLayer(this.params.kml, this.params.projection, 'KML');
if (this.params.georss) {
}
this.createGeoRSSLayer(this.params.georss, this.params.projection, 'GeoRSS');
}
if (this.params.csv) {
this.createCSVLayer(this.params.csv, this.params.projection, 'CSV');
}
if (this.params.bbox) {
var coords = this.params.bbox.split(',');
if (coords.length !== 4) {
Ext.window.MessageBox('Fehler', 'Eine BBOX enthält vier Koordinaten!');
}
else {
var numCoords = [];
for (var i = 0; i < 4; i++) {
numCoords.push(parseFloat(coords[i]));
}
this.map.getView().fit(
numCoords,
this.map.getSize());
}
}
if (this.params.x && this.params.y) {
if (!this.params.center) {
this.map.getView().setCenter([parseFloat(this.params.x), parseFloat(this.params.y)]);
}
var style = new ol.style.Style({
image: new ol.style.Icon({
src: window.bbviewerlib + 'img/markers/marker.png'
})
});
var source = new ol.source.Vector({
loader: function(extent, resolution, projection) {
var coordinate = ol.proj.transform([me.params.x, me.params.y], this.get('dataProjection'), projection);
var geom = new ol.geom.Point(coordinate);
var feature = new ol.Feature({
geometry: geom
});
this.addFeatures([feature]);
}
});
source.set('dataProjection', this.map.getView().getProjection());
var markerLayer = new ol.layer.Vector({
source: source,
style: style
});
this.map.addLayer(markerLayer);
}
if (this.params.center) {
var coords = this.params.center.split(',');
if (coords.length !== 2) {
Ext.window.MessageBox('Fehler', 'Kartenmitte kann nicht festgestellt werden!');
}
else {
var numCoords = [];
for (var i = 0; i < 2; i++) {
numCoords.push(parseFloat(coords[i]));
}
this.map.getView().setCenter(numCoords);
}
}
if (this.params.ort || this.params.strasse || this.params. plz) {
var text = this.params.strasse ? this.params.strasse + ' ' : '';
text += this.params.ort ? this.params.ort + ' ' : '';
text += this.params.plz ? this.params.plz : '';
var store = this.getLocationResultStore();
var epsg = this.map.getView().getProjection().getCode();
store.load({
params: {
Filter: text,
Typename: '0',
srsName: epsg,
maxFeatures: '50'
},
callback: this.loadLocations,
scope: this
});
}
if (this.params.geomaerker
&& this.params.geomaerker === 'true'
&& me.getController('Geomaerker')
&& me.application.appParams.app.tools.geomaerker) {
var btn = Ext.ComponentQuery
.query('toolbarview[id=top_toolbar] button[action=geomaerker]');
me.getController('Toolbar').geomaerker(btn[0]);
me.getController('Geomaerker').toggle(true, btn[0].lastBox.x);
}
LGB.ext4map.app.getController('LayerTree').disableLayers();
},
/**
* Manages the layertree entry for the @Param layer.
* @Param true if the layer is set to be checked in the layerTree
*/
toggleLayerTree: function(layer, toggleOn){
if (LGB.ext4map.app.controllerExists('LayerTree') && layer){
var view = Ext.ComponentQuery.query('layertree')[0];
var root = view.getRootNode();
var node = root.findChildBy(function(item) {
if (item.data.layerID == layer.get('layerID')) {
return true;
}
return false;
}, this, true);
//If no node is found, the layer is probably a sublayer;
if (!node) {
return;
}
if (toggleOn) {
node.set('checked', true);
this.getController('LayerTree').onItemCheckChange(node);
var parentNode = node.parentNode;
while (parentNode) {
parentNode.expand();
parentNode = parentNode.parentNode;
}
} else {
if (node){
node.set('checked', false);
}
}
view.store.sync();
}
},
switchProjection: function() {
if (!LGB.ext4map.app.controllerExists('ProjectionSwitcher')) {
return false;
}
var projection = '';
var configs = this.application.appParams.map;
var opts;
for (var i = 0; i < configs.length; i++) {
if (configs[i].switcherValue == this.params.projection) {
projection = ol.proj.get(this.params.projection);
opts = configs[i];
}
}
if (projection === '') {
return false;
}
if (Ext.getCmp('projectionswitcher')){
Ext.getCmp('projectionswitcher').select(this.params.projection);
}
var projection = ol.proj.get(this.params.projection);
var oldProjection = this.map.getView().getProjection();
var centerCoord = this.map.getView().getCenter();
var center = ol.proj.transform(centerCoord, oldProjection, projection);
var toolbox = Ext.create('LGB.ext4map.util.Toolbox');
var viewOpts = {
projection: projection,
center: center,
zoom: this.map.getView().getZoom()
};
if (opts.resolutions !== undefined) {
viewOpts.resolutions = opts.resolutions;
}
else if (opts.scales !== undefined) {
var resolutions = [];
for (var i = 0; i < opts.scales.length; i++) {
resolutions.push(
toolbox.getResolutionFromScale(opts.scales[i],
projection.getUnits()));
}
viewOpts.resolutions = resolutions;
}
else if (opts.maxZoom !== undefined) {
viewOpts.maxZoom = opts.maxZoom;
if (opts.minZoom !== undefined) {
viewOpts.minZoom = opts.minZoom;
}
else {
viewOpts.minZoom = 0;
}
}
var view = new ol.View(viewOpts);
// var draw = this.application.getController('Draw');
// var features = draw.drawLayer.getSource().getFeatures();
this.map.setView(view);
var mapPanel = Ext.getCmp('mapId');
var ovMap = mapPanel.overview;
if (ovMap) {
this.map.removeControl(ovMap);
mapPanel.overview = null;
this.map.updateSize();
var overview = new ol.control.OverviewMap({
className: 'ol-overviewmap ol-custom-overviewmap',
view: new ol.View({
projection: this.map.getView().getProjection()
}),
layers: [this.map.getLayers().getArray()[0]],
collapsed: true,
collapsible: true
});
mapPanel.overview = overview;
this.map.addControl(overview);
}
//features = draw.drawLayer.getSource().getFeatures().slice(0);
var layers = this.map.getLayers().getArray();
for (i = 0; i < layers.length; i++) {
if (layers[i] instanceof ol.layer.Vector &&
layers[i].getSource().getFormat() instanceof ol.format.WFS) {
layers[i].getSource().getProjection() == projection;
layers[i].getSource().clear();
layers[i].getSource().changed();
}
else if(layers[i] instanceof ol.layer.Vector){
var fs = layers[i].getSource().getFeatures();
for (var j = 0; j < fs.length; j++) {
fs[j].getGeometry().transform(oldProjection, projection);
}
}
else if (layers[i] instanceof ol.layer.Tile) {
gridOpts = {
resolutions: viewOpts.resolutions,
extent: opts.maxExtent
};
var params = layers[i].getSource().getParams();
var url = layers[i].getSource().getUrls()[0];
layers[i].setSource(new ol.source.TileWMS({
url: url,
params: params,
wrapX: false,
noWrap: true,
tileGrid: new ol.tilegrid.TileGrid(gridOpts)
}));
layers[i].getSource().on('tileloadstart', this.layerLoader.loadStart, this.layerLoader);
layers[i].getSource().on('tileloadend', this.layerLoader.loadEnd, this.layerLoader);
layers[i].getSource().changed();
}
}
//for (var i = 0; i < features.length; i++) {
// features[i].getGeometry().transform(oldProjection, projection);
//}
//draw.drawLayer.getSource().addFeatures(features);
// Change the digits of the mousePosition according to the Projection
var projSwitcher = Ext.ComponentQuery.query('projectionswitcher');
var digit = 2;
if (projSwitcher && projSwitcher.length > 0) {
var proj = projSwitcher[0].value;
if (proj === 'EPSG:4326') {
digit = 5;
}
else {
digit = 2;
}
}
var mousePositions = Ext.ComponentQuery.query('mouseposition');
if (mousePositions.length > 0){
mousePositions[0].digits = digit;
}
this.map.updateSize();
return true;
},
/**
* Create a Vector layer and add the features found in the kml document.
*
* @param {String} url The URL.
* @param {String} title The layer title.
*/
createKMLLayer: function(url, proj, title) {
var format = new ol.format.KML({
extractStyles: true
});
if (proj) {
format.defaultDataProjection = ol.proj.get(proj);
}
else {
format.defaultDataProjection =
ol.proj.get(this.map.getView().getProjection().getCode());
}
var source = new ol.source.Vector({
format: format,
url: url
});
//TODO: Only use one format attribute
var layer = new ol.layer.Vector({
name: title,
source: source,
type: 'kml',
options: {
format: 'kml',
featureInfo: true,
hover: true
}
});
this.map.addLayer(layer);
//Wait for the kml layer to be ready, then zoom to the extent
var readyListener = function() {
if (layer.getSource().getState() === 'ready' &&
layer.getSource().getExtent()[0] != Infinity) {
this.map.getView().fit(layer.getSource().getExtent(), this.map.getSize());
if (this.params['zoom']) {
this.map.getView().setZoom(parseInt(this.params.zoom));
}
layer.un('change', readyListener, this);
}
}
layer.on('change', readyListener, this);
},
* Create a Vector layer and add the features found in the georss document.
*
* @param {String} url The Url
* @param {String} title The layer title
*/
createGeoRSSLayer: function(url, proj, title) {
// TODO Implement a GeoRSS parser or wait for OL 3...
},
/**
* Create a Vector layer and add the features found in the csv document.
*
* @param {String} url The URL.
* @param {String} title The layer title.
*/
createCSVLayer: function(url, proj, title) {
var me = this;
Ext.Ajax.request({
url: url,
success: function(response) {
var gj = csv2geojson.csv2geojson(response.responseText, {
latfield: 'y',
lonfield: 'x',
delimiter: ','
}, function(err, data) {
if (err) {
Ext.Msg.alert('Fehler!',
'Die angegebene CSV-Datei konnte nicht verarbeitet werden.');
return;
}
var source = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(data)
});
var layer = new ol.layer.Vector({
name: title,
source: source
});
me.map.addLayer(layer);
if (proj !== 'EPSG:4236') {
var features = layer.getSource().getFeatures();
for (var i = 0; i < features.length; i++) {
features[i].getGeometry().transform('EPSG:4326', proj);
}
}
});
},
failure: function(response) {
Ext.Msg.alert('Fehler!',
'Die angegebene CSV-Datei konnte nicht geladen werden.');
}
});
},
/**
* Zoom to the specified bbox.
*
* @param {OpenLayers.Bounds} bbox The bounds to zoom to.
*/
zoomTo: function(bbox) {
this.map.getView().fit(bbox, this.map.getSize());
},
/**
* @private
* Load the locations similar to the gazetteer search.
*/
loadLocations: function(records, operation, success) {
if (records.length > 1) {
this.showSelector();
}
else {
Ext.Ajax.request({
scope: this,
url: './ows/fassade.php?url=' + records[0].get('url'),
// url: records[0].get('url'),
success: this.readResponse
});
}
},
/**
* @private
* Open the gazetteer search window.
*/
showSelector: function() {
var view = Ext.create('LGB.ext4map.view.Gazetteer', {
features: {
searchAddress: true
},
closeAction: 'destroy'
});
view.show();
var layers = this.map.getLayers().getArray();
var hl, cl;
for (var i = 0; i < layers.length; i++) {
if (layers[i].get('name') === 'Ortsuche') {
hl = layers[i];
}
if (layers[i].get('name') === 'OrtsucheFix') {
cl = layers[i];
}
}
view.down('gazetteerpanel').updateResults(hl, cl, null, null, 'LocationResult');
},
/**
* Read the features from search response and display the result on the map
* or open the gazetteer search window.
*/
readResponse: function(response) {
var gml = new ol.format.WFS({
gmlFormat: new ol.format.ADVGML3()
});
features = gml.readFeatures(response.responseXML); //Array(OpenLayers.Feature.Vector)
if (features.length > 1) {
this.showSelector();
}
else {
var feat = features[0];
var layers = this.map.getLayers().getArray();
var cl;
for (var i = 0; i < layers.length; i++) {
if (layers[i].get('name') === 'OrtsucheFix') {
cl = layers[i];
}
}
cl.getSource().clear();
var geom = feat.getGeometry().clone();
var feature = new ol.Feature({
geometry: geom
});
cl.getSource().addFeatures([feature]);
cl.setVisible(true);
this.zoomToExtent(geom.getExtent());
}
}
});