1
2
3
4
5
6
7 package nl.mineleni.cbsviewer.servlet.wms;
8
9 import static nl.mineleni.cbsviewer.util.CookieNamesConstants.COOKIE_S;
10 import static nl.mineleni.cbsviewer.util.CookieNamesConstants.COOKIE_X;
11 import static nl.mineleni.cbsviewer.util.CookieNamesConstants.COOKIE_Y;
12 import static nl.mineleni.cbsviewer.util.CookieNamesConstants.COOKIE_baselyr;
13 import static nl.mineleni.cbsviewer.util.CookieNamesConstants.COOKIE_mapid;
14 import static nl.mineleni.cbsviewer.util.StringConstants.MAP_CACHE_DIR;
15 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_BGMAP;
16 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_CACHEDIR;
17 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_DOWNLOADLINK;
18 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_FEATUREINFO;
19 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_FGMAP_ALPHA;
20 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_KAART;
21 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_LEGENDAS;
22 import static nl.mineleni.cbsviewer.util.StringConstants.REQ_PARAM_MAPID;
23
24 import java.awt.BasicStroke;
25 import java.awt.Color;
26 import java.awt.Font;
27 import java.awt.FontMetrics;
28 import java.awt.Graphics2D;
29 import java.awt.RenderingHints;
30 import java.awt.image.BufferedImage;
31 import java.awt.image.RescaleOp;
32 import java.io.File;
33 import java.io.IOException;
34 import java.net.MalformedURLException;
35 import java.net.URL;
36 import java.util.HashSet;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.concurrent.ConcurrentHashMap;
40
41 import javax.imageio.ImageIO;
42 import javax.servlet.ServletConfig;
43 import javax.servlet.ServletContext;
44 import javax.servlet.ServletException;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47
48 import nl.mineleni.cbsviewer.servlet.AbstractWxSServlet;
49 import nl.mineleni.cbsviewer.servlet.wms.FeatureInfoResponseConverter.CONVERTER_TYPE;
50 import nl.mineleni.cbsviewer.servlet.wms.cache.BboxLayerCacheKey;
51 import nl.mineleni.cbsviewer.servlet.wms.cache.CachableString;
52 import nl.mineleni.cbsviewer.servlet.wms.cache.Cache;
53 import nl.mineleni.cbsviewer.servlet.wms.cache.CacheImage;
54 import nl.mineleni.cbsviewer.servlet.wms.cache.WMSCache;
55 import nl.mineleni.cbsviewer.util.AvailableLayersBean;
56 import nl.mineleni.cbsviewer.util.SpatialUtil;
57 import nl.mineleni.cbsviewer.util.xml.LayerDescriptor;
58
59 import org.geotools.data.ows.Layer;
60 import org.geotools.data.ows.StyleImpl;
61 import org.geotools.data.ows.WMSCapabilities;
62 import org.geotools.data.wms.WMSUtils;
63 import org.geotools.data.wms.WebMapServer;
64 import org.geotools.data.wms.request.GetFeatureInfoRequest;
65 import org.geotools.data.wms.request.GetLegendGraphicRequest;
66 import org.geotools.data.wms.request.GetMapRequest;
67 import org.geotools.data.wms.response.GetFeatureInfoResponse;
68 import org.geotools.data.wms.response.GetLegendGraphicResponse;
69 import org.geotools.data.wms.response.GetMapResponse;
70 import org.geotools.ows.ServiceException;
71 import org.opengis.geometry.BoundingBox;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75
76
77
78
79
80
81 public class WMSClientServlet extends AbstractWxSServlet {
82
83
84 private static final int NUMBER_CACHE_ELEMENTS = 1000;
85
86
87 private static final Logger LOGGER = LoggerFactory
88 .getLogger(WMSClientServlet.class);
89
90
91
92
93 private static CONVERTER_TYPE type = CONVERTER_TYPE.GMLTYPE;
94
95
96
97
98
99
100 private static final int MAP_DIMENSION = 512;
101
102
103
104
105
106
107 private static final int MAP_DIMENSION_MIDDLE = MAP_DIMENSION / 2;
108
109
110 private static final int MAX_FEATURE_COUNT = 10;
111
112
113 private static final long SECONDS_TO_CACHE_ELEMENTS = 60 * 60;
114
115
116 private static final long MILLISECONDS_TO_CACHE_ELEMENTS = SECONDS_TO_CACHE_ELEMENTS * 1000;
117
118
119 private static final long serialVersionUID = 4958212343847516071L;
120
121
122 private transient WebMapServer bgWMS;
123
124
125 private volatile Cache<String, CacheImage, BufferedImage> legendCache;
126
127
128 private volatile Cache<BboxLayerCacheKey, CacheImage, BufferedImage> fgWMSCache;
129
130
131 private volatile Cache<BboxLayerCacheKey, CachableString, String> featInfoCache;
132
133
134 private transient String[] bgWMSlayers;
135
136
137
138
139
140
141 private transient GetMapRequest getMapRequest;
142
143
144 private final transient AvailableLayersBean layers = new AvailableLayersBean();
145
146
147 private transient WMSCache bgWMSCache;
148
149
150 private transient WebMapServer lufoWMS;
151
152
153 private transient WMSCache bgWMSLuFoCache;
154
155
156 private transient String[] lufoWMSlayers;
157
158
159
160
161
162
163 private transient Map<String, WebMapServer> wmsServersCache;
164
165
166
167
168
169
170 @Override
171 public void destroy() {
172 this.bgWMSCache.clear();
173 this.bgWMSLuFoCache.clear();
174 this.wmsServersCache.clear();
175 this.legendCache.clear();
176 this.fgWMSCache.clear();
177 this.featInfoCache.clear();
178 super.destroy();
179 }
180
181
182
183
184
185
186
187
188
189
190
191 private void drawScaleBar(final BufferedImage image, final BoundingBox bbox) {
192
193
194 final int xOffset = 10;
195 final int fontSize = 12;
196 final int yOffset = MAP_DIMENSION - xOffset;
197 final Graphics2D g = image.createGraphics();
198 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
199 RenderingHints.VALUE_ANTIALIAS_ON);
200 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
201 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
202
203
204 final double scale = bbox.getWidth() / MAP_DIMENSION;
205
206 int barLength = MAP_DIMENSION / 2;
207
208 int dist = (int) (barLength * scale);
209
210 final int digits = (int) (Math.log(dist) / Math.log(10));
211 final double pow10 = Math.pow(10, digits);
212 final int iRounded = (int) (dist / pow10);
213 int barLen = 1;
214 if (iRounded > 5) {
215 barLen = 5;
216 } else if (iRounded > 2) {
217 barLen = 2;
218 }
219 dist = (int) (barLen * pow10);
220 barLength = (int) (dist / scale);
221
222
223
224 String units = "m";
225 if (dist >= 1000) {
226 dist = dist / 1000;
227 units = "km";
228 }
229
230 g.setColor(Color.BLACK);
231 g.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND,
232 BasicStroke.JOIN_ROUND));
233 g.drawLine(xOffset, yOffset, xOffset + barLength, yOffset);
234 g.drawLine(xOffset, yOffset, xOffset, yOffset - fontSize);
235 g.drawLine(xOffset + barLength, yOffset, xOffset + barLength, yOffset
236 - fontSize);
237
238 final Font font = new Font(Font.SANS_SERIF, Font.BOLD, fontSize);
239 final FontMetrics metrics = g.getFontMetrics(font);
240 g.setFont(font);
241 g.drawString(
242 dist + units,
243 (xOffset + (barLength / 2))
244 - (metrics.stringWidth(dist + units) / 2), yOffset
245 - metrics.getDescent() - 2);
246
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264 private BufferedImage getBackGroundMap(final BoundingBox bbox,
265 final String baseMapType, HttpServletResponse response)
266 throws ServletException {
267
268 GetMapRequest map;
269
270 switch (baseMapType.toLowerCase()) {
271 case "luchtfoto":
272 this.setCookie(response, COOKIE_baselyr, "luchtfoto");
273 if (this.bgWMSLuFoCache.containsKey(bbox)) {
274
275 LOGGER.debug("Achtergrond " + baseMapType
276 + " afbeelding uit de cache serveren.");
277 return this.bgWMSLuFoCache.getImage(bbox);
278 }
279 map = this.lufoWMS.createGetMapRequest();
280 if (this.lufoWMSlayers != null) {
281 for (final String lyr : this.lufoWMSlayers) {
282
283 map.addLayer(lyr, "");
284 }
285 } else {
286
287 for (final Layer layer : WMSUtils.getNamedLayers(this.lufoWMS
288 .getCapabilities())) {
289 map.addLayer(layer);
290 }
291 }
292 map.setFormat("image/jpeg");
293 break;
294 case "topografie":
295
296 default:
297 this.setCookie(response, COOKIE_baselyr, "topografie");
298 if (this.bgWMSCache.containsKey(bbox)) {
299
300 LOGGER.debug("Achtergrond " + baseMapType
301 + " afbeelding uit de cache serveren.");
302 return this.bgWMSCache.getImage(bbox);
303 }
304 map = this.bgWMS.createGetMapRequest();
305 if (this.bgWMSlayers != null) {
306 for (final String lyr : this.bgWMSlayers) {
307
308 map.addLayer(lyr, "");
309 }
310 } else {
311
312 for (final Layer layer : WMSUtils.getNamedLayers(this.bgWMS
313 .getCapabilities())) {
314 map.addLayer(layer);
315 }
316 }
317 map.setFormat("image/png");
318 }
319
320 map.setDimensions(MAP_DIMENSION, MAP_DIMENSION);
321 map.setTransparent(true);
322 map.setBGColour("0xffffff");
323 map.setExceptions("application/vnd.ogc.se_inimage");
324 map.setSRS("EPSG:28992");
325 map.setBBox(bbox);
326
327 LOGGER.debug("Achtergrond WMS url is: " + map.getFinalURL());
328
329 try {
330 final GetMapResponse mapResponse = this.bgWMS.issueRequest(map);
331 final BufferedImage image = ImageIO.read(mapResponse
332 .getInputStream());
333 switch (baseMapType.toLowerCase()) {
334 case "luchtfoto":
335 this.bgWMSLuFoCache.put(bbox, image, SECONDS_TO_CACHE_ELEMENTS);
336 break;
337 case "topografie":
338
339 default:
340 this.bgWMSCache.put(bbox, image, SECONDS_TO_CACHE_ELEMENTS);
341 break;
342 }
343
344 if (LOGGER.isDebugEnabled()) {
345
346 final File temp = File.createTempFile(
347 "bgwms",
348 ".png",
349 new File(this.getServletContext().getRealPath(
350 MAP_CACHE_DIR.code)));
351 temp.deleteOnExit();
352 ImageIO.write(image, "png", temp);
353 }
354
355 return image;
356 } catch (ServiceException | IOException e) {
357 LOGGER.error(
358 "Er is een fout opgetreden bij het benaderen van de achtergrond WMS service.",
359 e);
360 throw new ServletException(e);
361 }
362
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376 private WebMapServer getCachedWMS(final LayerDescriptor lyrDesc)
377 throws ServiceException, IOException {
378 if (this.wmsServersCache.containsKey(lyrDesc.getUrl())) {
379 LOGGER.debug("WMS gevonden in cache.");
380 return this.wmsServersCache.get(lyrDesc.getUrl());
381 } else {
382 LOGGER.debug("Aanmaken van nieuwe WMS (inclusief versie onderhandeling).");
383 final WebMapServer fgWMS = new WebMapServer(new URL(
384 lyrDesc.getUrl()));
385 this.wmsServersCache.put(lyrDesc.getUrl(), fgWMS);
386 return fgWMS;
387 }
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 private String getFeatureInfo(final BoundingBox bbox,
405 final LayerDescriptor lyrDesc) throws ServiceException, IOException {
406 final BboxLayerCacheKey key = new BboxLayerCacheKey(bbox, lyrDesc);
407 if (this.featInfoCache.containsKey(key)) {
408
409 final CachableString fInfo = this.featInfoCache.get(key);
410 if (null != fInfo) {
411
412 LOGGER.debug("FeatureInfo uit de cache serveren.");
413 return fInfo.getItem();
414 }
415 }
416
417 try {
418 final GetFeatureInfoRequest getFeatureInfoRequest = this
419 .getCachedWMS(lyrDesc).createGetFeatureInfoRequest(
420 this.getMapRequest);
421
422 final String[] layerNames = lyrDesc.getLayers().split(",\\s*");
423 final Set<Layer> queryLayers = new HashSet<>();
424 final WMSCapabilities caps = this.getCachedWMS(lyrDesc)
425 .getCapabilities();
426
427 for (final Layer wmsLyr : caps.getLayerList()) {
428 if ((wmsLyr.getName() != null)
429 && (wmsLyr.getName().length() != 0)) {
430 for (final String layerName : layerNames) {
431 if (wmsLyr.getName().equalsIgnoreCase(layerName)) {
432 queryLayers.add(wmsLyr);
433 }
434 }
435 }
436 }
437 getFeatureInfoRequest.setQueryLayers(queryLayers);
438 getFeatureInfoRequest.setFeatureCount(MAX_FEATURE_COUNT);
439 getFeatureInfoRequest.setQueryPoint(MAP_DIMENSION_MIDDLE,
440 MAP_DIMENSION_MIDDLE);
441 getFeatureInfoRequest.setInfoFormat(type.toString());
442 LOGGER.debug("WMS feature info request url is: "
443 + getFeatureInfoRequest.getFinalURL());
444 final GetFeatureInfoResponse response = this.getCachedWMS(lyrDesc)
445 .issueRequest(getFeatureInfoRequest);
446
447 final String html = FeatureInfoResponseConverter
448 .convertToHTMLTable(response.getInputStream(), type,
449 lyrDesc);
450 this.featInfoCache.put(key,
451 new CachableString(html, System.currentTimeMillis()
452 + MILLISECONDS_TO_CACHE_ELEMENTS));
453 return html;
454
455 } catch (final UnsupportedOperationException u) {
456 LOGGER.warn("De WMS server ("
457 + this.getCachedWMS(lyrDesc).getInfo().getTitle()
458 + ") ondersteund geen GetFeatureInfoRequest.", u);
459 return "";
460 }
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475 private BufferedImage getForeGroundMap(final BoundingBox bbox,
476 final LayerDescriptor lyrDesc) throws ServletException {
477
478 final BboxLayerCacheKey key = new BboxLayerCacheKey(bbox, lyrDesc);
479 if (this.fgWMSCache.containsKey(key)) {
480
481 final CacheImage cImg = this.fgWMSCache.get(key);
482 if (null != cImg) {
483 LOGGER.debug("Voorgrond afbeelding uit de cache serveren.");
484 return cImg.getImage();
485 }
486 }
487
488
489 try {
490 this.getMapRequest = this.getCachedWMS(lyrDesc)
491 .createGetMapRequest();
492 final String[] layerNames = lyrDesc.getLayers().split(",\\s*");
493 final String[] styleNames = lyrDesc.getStyles().split(",\\s*");
494
495 for (int l = 0; l < layerNames.length; l++) {
496 this.getMapRequest.addLayer(layerNames[l], styleNames[l]);
497 }
498 this.getMapRequest.setFormat("image/png");
499 this.getMapRequest.setDimensions(MAP_DIMENSION, MAP_DIMENSION);
500 this.getMapRequest.setTransparent(true);
501 this.getMapRequest.setSRS("EPSG:28992");
502 this.getMapRequest.setBBox(bbox);
503 this.getMapRequest.setExceptions("application/vnd.ogc.se_inimage");
504 this.getMapRequest.setBGColour("0xffffff");
505 LOGGER.debug("Voorgrond WMS url is: "
506 + this.getMapRequest.getFinalURL());
507
508
509 final GetMapResponse response = this.getCachedWMS(lyrDesc)
510 .issueRequest(this.getMapRequest);
511 final BufferedImage image = ImageIO.read(response.getInputStream());
512 this.drawScaleBar(image, bbox);
513 this.fgWMSCache.put(key, new CacheImage(image,
514 SECONDS_TO_CACHE_ELEMENTS));
515
516 if (LOGGER.isDebugEnabled()) {
517
518 final File temp = File.createTempFile(
519 "fgwms",
520 ".png",
521 new File(this.getServletContext().getRealPath(
522 MAP_CACHE_DIR.code)));
523 temp.deleteOnExit();
524 ImageIO.write(image, "png", temp);
525 }
526 return image;
527 } catch (ServiceException | IOException e) {
528 LOGGER.error(
529 "Er is een fout opgetreden bij het benaderen van de voorgrond WMS service.",
530 e);
531 throw new ServletException(e);
532 }
533 }
534
535
536
537
538
539
540
541
542
543
544
545
546
547 private File[] getLegends(final LayerDescriptor lyrDesc)
548 throws ServiceException, IOException {
549 if (null == this.getCachedWMS(lyrDesc).getCapabilities().getRequest()
550 .getGetLegendGraphic()) {
551 LOGGER.debug("getGetLegendGraphic tested null, server ondersteund geen getGetLegendGraphic request.");
552 return this.getLegendsFromLayerStyles(lyrDesc);
553 } else {
554 return this.getLegendsFromService(lyrDesc);
555 }
556 }
557
558
559
560
561
562
563
564
565
566
567
568
569
570 private File[] getLegendsFromLayerStyles(final LayerDescriptor lyrDesc)
571 throws ServiceException, IOException {
572 final String[] layerNames = lyrDesc.getLayers().split(",\\s*");
573 final String[] styleNames = lyrDesc.getStyles().split(",\\s*");
574 final File[] legends = new File[layerNames.length];
575
576 for (int l = 0; l < layerNames.length; l++) {
577 final String key = layerNames[l] + "::" + styleNames[l];
578 if (this.legendCache.containsKey(key)) {
579
580
581 final CacheImage cImg = this.legendCache.get(key);
582 if (null != cImg) {
583
584 legends[l] = new File(cImg.getName());
585 if (!legends[l].exists()) {
586
587 ImageIO.write(this.legendCache.get(key).getImage(),
588 "png", legends[l]);
589 }
590 LOGGER.debug("Legenda bestand uit cache: "
591 + legends[l].getAbsolutePath());
592 }
593 } else {
594 for (final Layer layer : this.getCachedWMS(lyrDesc)
595 .getCapabilities().getLayerList()) {
596 if (layerNames[l].equalsIgnoreCase(layer.getName())) {
597
598 for (final StyleImpl style : layer.getStyles()) {
599 if (styleNames[l].equalsIgnoreCase(style.getName())) {
600
601 final String legendUrl = (String) style
602 .getLegendURLs().get(0);
603 LOGGER.debug("Legenda url uit capabilities is: "
604 + legendUrl);
605 if (this.isNotNullNotEmptyNotWhiteSpaceOnly(legendUrl)) {
606 try {
607 legends[l] = this.cacheLegend(ImageIO
608 .read(new URL(legendUrl)), key);
609 } catch (final MalformedURLException e) {
610 LOGGER.warn(
611 "Er werd geen geldige URL voor de legenda gevonden.",
612 e);
613 }
614 }
615 }
616 }
617 }
618 }
619 }
620 }
621 return legends;
622 }
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 private File[] getLegendsFromService(final LayerDescriptor lyrDesc)
638 throws ServiceException, IOException {
639 final String[] layerNames = lyrDesc.getLayers().split(",\\s*");
640 final String[] styleNames = lyrDesc.getStyles().split(",\\s*");
641 final File[] legends = new File[layerNames.length];
642
643 try {
644 final GetLegendGraphicRequest legend = this.getCachedWMS(lyrDesc)
645 .createGetLegendGraphicRequest();
646 for (int l = 0; l < layerNames.length; l++) {
647 final String key = layerNames[l] + "::" + styleNames[l];
648
649 if (this.legendCache.containsKey(key)) {
650
651
652 final CacheImage cImg = this.legendCache.get(key);
653 if (null != cImg) {
654
655 legends[l] = new File(cImg.getName());
656 if (!legends[l].exists()) {
657
658 ImageIO.write(this.legendCache.get(key).getImage(),
659 "png", legends[l]);
660 }
661 LOGGER.debug("Legenda bestand uit cache: "
662 + legends[l].getAbsolutePath());
663 }
664 } else {
665
666 legend.setLayer(layerNames[l]);
667 legend.setStyle(styleNames[l]);
668 legend.setFormat("image/png");
669 legend.setExceptions("application/vnd.ogc.se_inimage");
670
671 LOGGER.debug("Voorgrond WMS legenda url is: "
672 + legend.getFinalURL());
673 final GetLegendGraphicResponse response = this
674 .getCachedWMS(lyrDesc).issueRequest(legend);
675 legends[l] = this.cacheLegend(
676 ImageIO.read(response.getInputStream()), key);
677 }
678 }
679 } catch (final UnsupportedOperationException u) {
680 LOGGER.warn("De WMS server ("
681 + this.getCachedWMS(lyrDesc).getInfo().getTitle()
682 + ") ondersteund geen GetLegendGraphicRequest.", u);
683 return null;
684 }
685 return legends;
686 }
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701 private File getMap(final BufferedImage imageVoorgrond,
702 final BufferedImage imageAchtergrond, final float alpha)
703 throws IOException {
704
705 final BufferedImage composite = new BufferedImage(MAP_DIMENSION,
706 MAP_DIMENSION, BufferedImage.TYPE_INT_ARGB);
707 final Graphics2D g = composite.createGraphics();
708
709 g.drawImage(imageAchtergrond, 0, 0, null);
710 if (imageVoorgrond != null) {
711 final float[] scales = { 1f, 1f, 1f, alpha };
712 final RescaleOp rop = new RescaleOp(scales, new float[4], null);
713 g.drawImage(imageVoorgrond, rop, 0, 0);
714
715 final BufferedImage infoImage = ImageIO.read(new File(this
716 .getClass().getClassLoader().getResource("info.png")
717 .getFile()));
718
719
720 g.drawImage(infoImage, MAP_DIMENSION_MIDDLE - 16,
721 MAP_DIMENSION_MIDDLE - 36, null);
722
723 }
724
725 final File kaartAfbeelding = File.createTempFile(
726 "wmscombined",
727 ".png",
728 new File(this.getServletContext().getRealPath(
729 MAP_CACHE_DIR.code)));
730 kaartAfbeelding.deleteOnExit();
731 ImageIO.write(composite, "png", kaartAfbeelding);
732 g.dispose();
733 return kaartAfbeelding;
734 }
735
736
737
738
739
740
741
742
743
744
745
746
747 private File cacheLegend(final BufferedImage image, final String key)
748 throws IOException {
749
750 final File legend = File.createTempFile("legenda", ".png", new File(
751 this.getServletContext().getRealPath(MAP_CACHE_DIR.code)));
752 legend.deleteOnExit();
753 ImageIO.write(image, "png", legend);
754
755 this.legendCache.put(
756 key,
757 new CacheImage(image, legend.getAbsolutePath(), System
758 .currentTimeMillis()
759 + (MILLISECONDS_TO_CACHE_ELEMENTS * 24)));
760 LOGGER.debug("Legenda bestand opgeslagen: " + legend.getAbsolutePath());
761 return legend;
762 }
763
764
765
766
767
768
769
770
771 @Override
772 public void init(final ServletConfig config) throws ServletException {
773 super.init(config);
774 final ServletContext ctx = this.getServletContext();
775 try {
776 this.bgWMSCache = new WMSCache(ctx.getRealPath(MAP_CACHE_DIR.code),
777 NUMBER_CACHE_ELEMENTS);
778 } catch (final IOException e) {
779 LOGGER.error(
780 "Inititalisatie fout voor de achtergrond topografie cache.",
781 e);
782 }
783
784 try {
785 this.bgWMSLuFoCache = new WMSCache(
786 ctx.getRealPath(MAP_CACHE_DIR.code), NUMBER_CACHE_ELEMENTS);
787 } catch (final IOException e) {
788 LOGGER.error(
789 "Inititalisatie fout voor de achtergrond luchtfoto cache.",
790 e);
791 }
792
793 this.legendCache = new Cache<>(NUMBER_CACHE_ELEMENTS);
794
795 this.featInfoCache = new Cache<>(NUMBER_CACHE_ELEMENTS);
796
797 this.fgWMSCache = new Cache<>(NUMBER_CACHE_ELEMENTS);
798
799
800 final String bgCapabilitiesURL = config
801 .getInitParameter("bgCapabilitiesURL");
802 LOGGER.debug("WMS capabilities url van achtergrond kaart: "
803 + bgCapabilitiesURL);
804 try {
805 this.bgWMS = new WebMapServer(new URL(bgCapabilitiesURL));
806 } catch (final MalformedURLException e) {
807 LOGGER.error(
808 "Een url die gebruikt wordt voor de topografie WMS capabilities is misvormd",
809 e);
810 throw new ServletException(e);
811 } catch (final ServiceException e) {
812 LOGGER.error(
813 "Er is een service exception (WMS server fout) opgetreden bij het ophalen van de topografie WMS capabilities",
814 e);
815 throw new ServletException(e);
816 } catch (final IOException e) {
817 LOGGER.error(
818 "Er is een I/O fout opgetreden bij benaderen van de topografie WMS services",
819 e);
820 throw new ServletException(e);
821 }
822 final String bgWMSlyrs = config.getInitParameter("bgWMSlayers");
823 LOGGER.debug("Achtergrond kaartlagen topografie: " + bgWMSlyrs);
824 if ((bgWMSlyrs != null) && (bgWMSlyrs.length() > 0)) {
825 this.bgWMSlayers = bgWMSlyrs.split("[,]\\s*");
826 }
827
828
829 final String lufoCapabilitiesURL = config
830 .getInitParameter("lufoCapabilitiesURL");
831 LOGGER.debug("WMS capabilities url van achtergrond luchtfoto: "
832 + lufoCapabilitiesURL);
833 try {
834 this.lufoWMS = new WebMapServer(new URL(lufoCapabilitiesURL));
835 } catch (final MalformedURLException e) {
836 LOGGER.error(
837 "De url die gebruikt wordt voor de luchtfoto WMS capabilities is misvormd",
838 e);
839 throw new ServletException(e);
840 } catch (final ServiceException e) {
841 LOGGER.error(
842 "Er is een service exception (WMS server fout) opgetreden bij het ophalen van de luchtfoto WMS capabilities",
843 e);
844 throw new ServletException(e);
845 } catch (final IOException e) {
846 LOGGER.error(
847 "Er is een I/O fout opgetreden bij benaderen van de luchtfoto WMS services",
848 e);
849 throw new ServletException(e);
850 }
851 final String lufoWMSlyrs = config.getInitParameter("lufoWMSlayers");
852 LOGGER.debug("Achtergrond kaartlagen luchtfoto: " + lufoWMSlyrs);
853 if ((lufoWMSlyrs != null) && (lufoWMSlyrs.length() > 0)) {
854 this.lufoWMSlayers = lufoWMSlyrs.split("[,]\\s*");
855 }
856
857
858 final String mType = config.getInitParameter("featureInfoType");
859 LOGGER.debug("voorgrond kaartlagen mimetype: " + mType);
860 if ((mType != null) && (mType.length() > 0)) {
861 type = CONVERTER_TYPE.valueOf(mType);
862 }
863
864 this.wmsServersCache = new ConcurrentHashMap<String, WebMapServer>();
865 }
866
867
868
869
870
871
872
873 @Override
874 protected void service(final HttpServletRequest request,
875 final HttpServletResponse response) throws ServletException,
876 IOException {
877
878 final int[] dXcoordYCoordStraal = this.parseLocation(request);
879 final int xcoord = dXcoordYCoordStraal[0];
880 final int ycoord = dXcoordYCoordStraal[1];
881 final int straal = dXcoordYCoordStraal[2];
882 final BoundingBox bbox = SpatialUtil.calcRDBBOX(xcoord, ycoord, straal);
883
884 this.setCookie(response, COOKIE_X, xcoord);
885 this.setCookie(response, COOKIE_Y, ycoord);
886 this.setCookie(response, COOKIE_S, straal);
887
888 float alpha = 0.8f;
889 final String trans = request.getParameter(REQ_PARAM_FGMAP_ALPHA.code);
890 if (this.isNotNullNotEmptyNotWhiteSpaceOnly(trans)) {
891
892 try {
893 alpha = 1 - (Float.parseFloat(trans) / 100);
894 if ((0 > alpha) && (alpha > 1)) {
895 alpha = 0.8f;
896 }
897 } catch (final NumberFormatException n) {
898 alpha = 0.8f;
899 }
900
901 }
902 LOGGER.debug("Transparantie / alpha ingesteld op:" + alpha);
903
904 String basemaptype = "topografie";
905 final String mType = request.getParameter(REQ_PARAM_BGMAP.code);
906 if (this.isNotNullNotEmptyNotWhiteSpaceOnly(mType)) {
907 basemaptype = mType;
908 }
909 final BufferedImage bg = this.getBackGroundMap(bbox, basemaptype,
910 response);
911
912 BufferedImage fg = null;
913 final String mapid = request.getParameter(REQ_PARAM_MAPID.code);
914 if (this.isNotNullNotEmptyNotWhiteSpaceOnly(mapid)) {
915 this.setCookie(response, COOKIE_mapid, mapid);
916 final LayerDescriptor layer = this.layers.getLayerByID(mapid);
917 request.setAttribute("mapname", layer.getName());
918 LOGGER.debug("LayerDescriptor::Name is: " + layer.getName());
919
920 final String fgCapabilitiesURL = layer.getUrl();
921 LOGGER.debug("WMS capabilities url van voorgrond kaart: "
922 + fgCapabilitiesURL);
923 try {
924 fg = this.getForeGroundMap(bbox, layer);
925 final File[] legendas = this.getLegends(layer);
926 final String fInfo = this.getFeatureInfo(bbox, layer);
927 request.setAttribute(REQ_PARAM_MAPID.code, mapid);
928 request.setAttribute(REQ_PARAM_LEGENDAS.code, legendas);
929 request.setAttribute(REQ_PARAM_FEATUREINFO.code, fInfo);
930 request.setAttribute(REQ_PARAM_DOWNLOADLINK.code,
931 layer.getLink());
932 } catch (final ServiceException e) {
933 LOGGER.error(
934 "Er is een service exception opgetreden bij benaderen van de voorgrond WMS",
935 e);
936 throw new ServletException(e);
937 } catch (final MalformedURLException e) {
938 LOGGER.error(
939 "De url die gebruikt wordt voor de WMS capabilities is misvormd.",
940 e);
941 throw new ServletException(e);
942 }
943 }
944
945 final File kaart = this.getMap(fg, bg, alpha);
946
947 request.setAttribute(REQ_PARAM_CACHEDIR.code, MAP_CACHE_DIR.code);
948 request.setAttribute(REQ_PARAM_KAART.code, kaart);
949 request.setAttribute(REQ_PARAM_BGMAP.code, basemaptype);
950 }
951 }