Печать базовой карты OSM с использованием модуля MapFish Print
Я пытаюсь заставить работать функцию GeoExt MapFishPrintProvider, упомянутую в этом другом посте. Тем не менее, страница загружается, чтобы показать пустую страницу с сообщением об ошибке:
"Error while processing request: java.lang.NullPointerException".
У меня есть слой базовой карты OSM, который вызывает исключение java.lang.NullPointerException. Я предполагаю, что это по двум причинам: 1) примеры печати mapfish, использующие слои osm, дают ту же ошибку, и 2) удаление слоя osm приводит к успешной печати.
Я попытался загрузить модули следующим образом:
Ext.define('SIG.view.main.Main', {
extend: 'Ext.container.Viewport',
requires: [
'Ext.plugin.Viewport',
'Ext.window.MessageBox',
'SIG.view.main.MainController',
'SIG.view.main.MainModel',
'SIG.view.main.List',
'SIG.view.main.Map',
'GeoExt.data.serializer.Base',
'GeoExt.data.serializer.ImageWMS',
'GeoExt.data.serializer.TileWMS',
'GeoExt.data.serializer.Vector',
'GeoExt.data.serializer.WMTS',
'GeoExt.data.serializer.XYZ'
],
controller: 'main',
viewModel: 'main',
layout: 'border',
items: [
mapComponent,
layerTreePanel
]
});
Карта и компонент карты были созданы таким образом.
window.my_map = new ol.Map({
controls: ol.control.defaults().extend([new ol.control.ScaleLine]),
target: 'map',
view: view,
layers: [
new ol.layer.Group({title: 'Fond de plans', layers: [osm_basemap], name: 'Fond de plans'}),
new ol.layer.Group({title: 'Réseau Secosud', layers: [coupureaerien_layer], name: 'Réseau Secosud'}),
extentLayer
],
//overlays: [overlay],
});
var mapComponent = Ext.create('GeoExt.component.Map', {
map: window.my_map,
controller: 'main-map',
listeners: {
render: function(){
//console.log('Map rendered');
Ext.create('GeoExt.data.MapfishPrintProvider', {
url: 'http://ourserver:8081/print/' +
'print/geoext/capabilities.json',
listeners: {
ready: onPrintProviderReady
}
});
}
}
});
Это функции, которые используют инструмент GeoExt3 getSerializedLayers, который, как я предполагаю, вызывает ошибку.
var unHttpsLayers = function(layers) {
var changed = [];
Ext.each(layers, function(layer) {
var clone = Ext.clone(layer);
if (clone.baseURL && (/^https:/i).test(clone.baseURL)) {
clone.baseURL = clone.baseURL.replace('https', 'http');
}
changed.push(clone);
});
return changed;
};
var onPrintProviderReady = function(provider) {
// this is the assumption: take the first layout and render an
// appropriate extent on the map
var capabilities = provider.capabilityRec;
var layout = capabilities.layouts().getAt(0);
var attr = layout.attributes().getAt(0);
var clientInfo = attr.get('clientInfo');
var render = GeoExt.data.MapfishPrintProvider.renderPrintExtent;
console.log(mapComponent);
render(mapComponent, extentLayer, clientInfo);
mapComponent.getView().on('propertychange', function() {
extentLayer.getSource().clear();
render(mapComponent, extentLayer, clientInfo);
});
var printButton = document.getElementById('print_button-btnInnerEl');
printButton.addEventListener("click", (function() {
console.log('got here');
var spec = {
layout: layout.get('name'),
attributes: {}
};
console.log(spec);
var firstFeature = extentLayer.getSource().getFeatures()[0];
var bbox = firstFeature.getGeometry().getExtent();
var util = GeoExt.data.MapfishPrintProvider;
var mapView = mapComponent.getView();
var serializedLayers = util.getSerializedLayers(
mapComponent,
function(layer) {
// do not print the extent layer
var isExtentLayer = (extentLayer === layer);
return !isExtentLayer;
}
);
console.log(serializedLayers);
serializedLayers = unHttpsLayers(serializedLayers);
serializedLayers.reverse();
console.log(serializedLayers);
spec.attributes[attr.get('name')] = {
bbox: bbox,
dpi: clientInfo.dpiSuggestions[0],
layers: serializedLayers,
projection: mapView.getProjection().getCode(),
rotation: mapView.getRotation()
};
Ext.create('Ext.form.Panel', {
standardSubmit: true,
url: 'http://ourserver:8081/print/' +
'print/geoext/buildreport.pdf',
method: 'POST',
items: [
{
xtype: 'textfield',
name: 'spec',
value: Ext.encode(spec)
}
]
}).submit();
}));
};
Файл config.yaml, который находится в корне каталога модуля print-app в сервлете.
throwErrorOnExtraParameters: true
templates:
A4 portrait: !template
reportTemplate: simpleReport.jrxml
attributes:
map: !map
maxDpi: 400
width: 780
height: 330
processors:
- !reportBuilder # compile all reports in current directory
directory: '.'
- !createMap {}
Распечатывая спецификации на консоль, я получаю следующее. Единственное, что я сейчас изучаю, - это то, что мой базовый URL был проанализирован на предмет включения "/{z}/{x}/{y}/ ", тогда как многие примеры заканчиваются на " http://a.tile.openstreetmap.org/":
{"layout":"A4 portrait",
"attributes":
{"map":
{"bbox":[-16646158.733074246,-2014058.743123461,-16557461.205452127,-1976532.8660525647],
"dpi":72,
"layers":[
{"baseURL":"http://ourserver:8081/geoserver/wms?",
"customParams": {"LAYERS":"tahiti:elec_edt_appareil_coupure_aerien_hta",
"FORMAT":"image/png",
"TILED":true},
"layers":["tahiti:elec_edt_appareil_coupure_aerien_hta"],
"opacity":1,
"styles":[""],
"type":"WMS"},
{"baseURL":"http://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
"opacity":1,
"imageExtension":"png",
"resolutions":[156543.03392804097,78271.51696402048,39135.75848201024,19567.87924100512,9783.93962050256,4891.96981025128,2445.98490512564,1222.99245256282,611.49622628141,305.748113140705,152.8740565703525,76.43702828517625,38.21851414258813,19.109257071294063,9.554628535647032,4.777314267823516,2.388657133911758,1.194328566955879,0.5971642834779395,0.29858214173896974],
"tileSize":[256,256],
"type":"OSM"}],
"projection":"EPSG:3857",
"rotation":0}
}
}