comparison flys-artifacts/src/main/java/de/intevation/flys/utils/MapfileGenerator.java @ 4654:861c47e0a8a0

Refactor Mapserver mapfile generation. Prepares the existing mapfile generation code for a river axis mapfile generator. Removes unused asynchronous mapfile generation to reduce complexity.
author Christian Lins <christian.lins@intevation.de>
date Sat, 08 Dec 2012 00:19:29 +0100
parents c04db3178d09
children 442fbb290fa8
comparison
equal deleted inserted replaced
4653:a93699cb31eb 4654:861c47e0a8a0
1 package de.intevation.flys.utils; 1 package de.intevation.flys.utils;
2 2
3 import de.intevation.artifacts.CallContext;
4 import de.intevation.artifacts.common.utils.Config; 3 import de.intevation.artifacts.common.utils.Config;
5 import de.intevation.flys.artifacts.FLYSArtifact;
6 import de.intevation.flys.artifacts.model.LayerInfo; 4 import de.intevation.flys.artifacts.model.LayerInfo;
7 import de.intevation.flys.artifacts.model.RiverFactory;
8 import de.intevation.flys.artifacts.model.map.WMSDBLayerFacet;
9 import de.intevation.flys.artifacts.model.map.WMSLayerFacet;
10 import de.intevation.flys.artifacts.model.map.WSPLGENLayerFacet;
11 import de.intevation.flys.artifacts.resources.Resources;
12 import de.intevation.flys.model.River;
13 5
14 import java.io.File; 6 import java.io.File;
15 import java.io.FileNotFoundException; 7 import java.io.FileNotFoundException;
16 import java.io.FileWriter; 8 import java.io.FileWriter;
17 import java.io.FilenameFilter; 9 import java.io.FilenameFilter;
23 15
24 import org.apache.log4j.Logger; 16 import org.apache.log4j.Logger;
25 import org.apache.velocity.Template; 17 import org.apache.velocity.Template;
26 import org.apache.velocity.VelocityContext; 18 import org.apache.velocity.VelocityContext;
27 import org.apache.velocity.app.VelocityEngine; 19 import org.apache.velocity.app.VelocityEngine;
28 import org.geotools.data.shapefile.ShpFiles;
29 import org.geotools.data.shapefile.shp.ShapefileHeader;
30 import org.geotools.data.shapefile.shp.ShapefileReader;
31 20
32 /** 21 /**
33 * This class iterates over a bunch of directories, searches for meta 22 * This class iterates over a bunch of directories, searches for meta
34 * information coresponding to shapefiles and creates a mapfile which is used by 23 * information coresponding to shapefiles and creates a mapfile which is used by
35 * a <i>MapServer</i>. 24 * a <i>MapServer</i>.
36 * 25 *
37 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 26 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
38 */ 27 */
39 public class MapfileGenerator 28 public abstract class MapfileGenerator
40 extends Thread
41 { 29 {
42 public static final String WSPLGEN_RESULT_SHAPE = "wsplgen.shp"; 30 public static final String WSPLGEN_RESULT_SHAPE = "wsplgen.shp";
43 public static final String WSPLGEN_LINES_SHAPE = "barrier_lines.shp"; 31 public static final String WSPLGEN_LINES_SHAPE = "barrier_lines.shp";
44 public static final String WSPLGEN_POLYGONS_SHAPE = "barrier_polygons.shp"; 32 public static final String WSPLGEN_POLYGONS_SHAPE = "barrier_polygons.shp";
45 public static final String WSPLGEN_USER_SHAPE = "user-rgd.shp"; 33 public static final String WSPLGEN_USER_SHAPE = "user-rgd.shp";
54 public static final String MS_LINE_PREFIX = "lines-"; 42 public static final String MS_LINE_PREFIX = "lines-";
55 public static final String MS_POLYGONS_PREFIX = "polygons-"; 43 public static final String MS_POLYGONS_PREFIX = "polygons-";
56 public static final String MS_LAYER_PREFIX = "ms_layer-"; 44 public static final String MS_LAYER_PREFIX = "ms_layer-";
57 public static final String MS_USERSHAPE_PREFIX = "user-"; 45 public static final String MS_USERSHAPE_PREFIX = "user-";
58 46
59 protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds
60
61 private static Logger logger = Logger.getLogger(MapfileGenerator.class); 47 private static Logger logger = Logger.getLogger(MapfileGenerator.class);
62 48
63 private static MapfileGenerator instance;
64
65 private File shapefileDirectory; 49 private File shapefileDirectory;
66 50
67 private VelocityEngine velocityEngine; 51 private VelocityEngine velocityEngine;
68 private final boolean lock[]; 52
69 53
70 54 protected MapfileGenerator() {
71 55 }
72 private MapfileGenerator() { 56
73 lock = new boolean[1];
74 }
75
76
77 /**
78 * A main method which can be used to create a mapfile without a running
79 * artifact server.<br>
80 * <b>NOTE:</b> This method is not implemented yet!
81 *
82 * @param args Arguments.
83 */
84 public static void main(String[] args) {
85 throw new Error("MapfileGenerator.main() is CURRENTLY NOT IMPLEMENTED!");
86 }
87
88
89 /**
90 * Returns the instance of this generator.
91 *
92 * @return the instance.
93 */
94 public static synchronized MapfileGenerator getInstance() {
95 if (instance == null) {
96 instance = new MapfileGenerator();
97 instance.setDaemon(true);
98 instance.start();
99 }
100
101 return instance;
102 }
103
104
105 /**
106 * Triggers the mapfile generation process.
107 */
108 public void update() {
109 synchronized (lock) {
110 logger.debug("update");
111 lock[0] = true;
112 lock.notify();
113 }
114 }
115
116
117 /**
118 * Thread to generate a mapfile.
119 */
120 @Override
121 public void run() {
122 logger.debug("Start MapfileGenerator thread...");
123 try {
124 for (;;) {
125 synchronized (lock) {
126 while (!lock[0]) {
127 lock.wait(SLEEPTIME);
128 }
129 lock[0] = false;
130 }
131
132 logger.debug("Start sync process now...");
133 generate();
134 }
135 }
136 catch (InterruptedException ie) {
137 logger.debug("MapfileGenerator thread got an interrupt.");
138 }
139 catch (FileNotFoundException fnfe) {
140 logger.debug("Error while mapfile creation: " + fnfe.getMessage());
141 }
142 catch (IOException ioe) {
143 logger.error(ioe, ioe);
144 }
145 finally {
146 logger.debug("THREAD END");
147 }
148 }
149 57
150 /** 58 /**
151 * Method to check the existance of a template file. 59 * Method to check the existance of a template file.
152 * 60 *
153 * @param templateID The name of a template. 61 * @param templateID The name of a template.
157 Template template = getTemplateByName(templateID); 65 Template template = getTemplateByName(templateID);
158 return template != null; 66 return template != null;
159 } 67 }
160 68
161 69
162 /** 70 protected abstract void generate() throws Exception;
163 * Method which starts searching for meta information file and mapfile
164 * generation.
165 */
166 protected void generate()
167 throws FileNotFoundException, IOException
168 {
169 File[] userDirs = getUserDirs();
170
171 List<String> layers = parseLayers(userDirs);
172
173 logger.info("Found " + layers.size() + " layers for user mapfile.");
174
175 writeMapfile(layers);
176 }
177
178
179 /**
180 * Generate river axis mapfile.
181 */
182 protected void generateRiverAxisMapfile() {
183 List<River> rivers = RiverFactory.getRivers();
184
185 for (River river : rivers) {
186 createRiverAxisLayer(
187 river.getName(),
188 river.getId(),
189 "41677",
190 "100,100,100,100");
191 }
192 }
193 71
194 72
195 /** 73 /**
196 * Returns the VelocityEngine used for the template mechanism. 74 * Returns the VelocityEngine used for the template mechanism.
197 * 75 *
377 255
378 return layers; 256 return layers;
379 } 257 }
380 258
381 259
382 /**
383 * Creates a layer file used for Mapserver's mapfile which represents the
384 * floodmap.
385 *
386 * @param flys The FLYSArtifact that owns <i>wms</i>.
387 * @param wms The WMSLayerFacet that contains information for the layer.
388 */
389 public void createUeskLayer(
390 FLYSArtifact flys,
391 WSPLGENLayerFacet wms,
392 String style,
393 CallContext context
394 ) throws FileNotFoundException, IOException
395 {
396 logger.debug("createUeskLayer");
397
398 LayerInfo layerinfo = new LayerInfo();
399 layerinfo.setName(MS_WSPLGEN_PREFIX + flys.identifier());
400 layerinfo.setType("POLYGON");
401 layerinfo.setDirectory(flys.identifier());
402 layerinfo.setData(WSPLGEN_RESULT_SHAPE);
403 layerinfo.setTitle(Resources.getMsg(Resources.getLocale(context.getMeta()),
404 "floodmap.uesk",
405 "Floodmap"));
406 layerinfo.setStyle(style);
407 layerinfo.setSrid(wms.getSrid());
408
409 String name = MS_LAYER_PREFIX + wms.getName();
410
411 Template template = getTemplateByName(WSPLGEN_LAYER_TEMPLATE);
412 if (template == null) {
413 logger.warn("Template '" + WSPLGEN_LAYER_TEMPLATE + "' found.");
414 return;
415 }
416
417 try {
418 File dir = new File(getShapefileBaseDir(), flys.identifier());
419 writeLayer(layerinfo, dir, name, template);
420 }
421 catch (FileNotFoundException fnfe) {
422 logger.error(fnfe, fnfe);
423 logger.warn("Unable to write layer: " + name);
424 }
425 }
426
427
428 /**
429 * Creates a layer file used for Mapserver's mapfile which represents the
430 * user defined barriers.
431 *
432 * @param flys The FLYSArtifact that owns <i>wms</i>.
433 * @param wms The WMSLayerFacet that contains information for the layer.
434 */
435 public void createBarriersLayer(FLYSArtifact flys, WMSLayerFacet wms)
436 throws FileNotFoundException, IOException
437 {
438 logger.debug("createBarriersLayer");
439
440 //String uuid = flys.identifier();
441 //File dir = new File(getShapefileBaseDir(), uuid);
442
443 createBarriersLineLayer(flys, wms);
444 createBarriersPolygonLayer(flys, wms);
445 }
446
447
448 protected void createBarriersLineLayer(
449 FLYSArtifact flys,
450 WMSLayerFacet wms
451 )
452 throws FileNotFoundException, IOException
453 {
454 String uuid = flys.identifier();
455 String group = MS_BARRIERS_PREFIX + uuid;
456 String groupTitle = "I18N_BARRIERS_TITLE";
457
458 File dir = new File(getShapefileBaseDir(), uuid);
459 File test = new File(dir, WSPLGEN_LINES_SHAPE);
460
461 if (!test.exists() || !test.canRead()) {
462 logger.debug("No barrier line layer existing.");
463 return;
464 }
465
466 LayerInfo lineInfo = new LayerInfo();
467 lineInfo.setName(MS_LINE_PREFIX + uuid);
468 lineInfo.setType("LINE");
469 lineInfo.setDirectory(uuid);
470 lineInfo.setData(WSPLGEN_LINES_SHAPE);
471 lineInfo.setTitle("I18N_LINE_SHAPE");
472 lineInfo.setGroup(group);
473 lineInfo.setGroupTitle(groupTitle);
474 lineInfo.setSrid(wms.getSrid());
475
476 String nameLines = MS_LAYER_PREFIX + wms.getName() + "-lines";
477
478 Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
479 if (tpl == null) {
480 logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
481 return;
482 }
483
484 try {
485 writeLayer(lineInfo, dir, nameLines, tpl);
486 }
487 catch (FileNotFoundException fnfe) {
488 logger.error(fnfe, fnfe);
489 logger.warn("Unable to write layer: " + nameLines);
490 }
491 }
492
493
494 protected void createRiverAxisLayer(String riverName, int riverID, String srid, String extend) {
495 LayerInfo layerInfo = new LayerInfo();
496 layerInfo.setName(riverName);
497 layerInfo.setSrid(srid);
498 layerInfo.setExtent(extend);
499 }
500
501
502 protected void createBarriersPolygonLayer(
503 FLYSArtifact flys,
504 WMSLayerFacet wms
505 )
506 throws FileNotFoundException, IOException
507 {
508 String uuid = flys.identifier();
509 String group = uuid + MS_BARRIERS_PREFIX;
510 String groupTitle = "I18N_BARRIERS_TITLE";
511
512 File dir = new File(getShapefileBaseDir(), uuid);
513 File test = new File(dir, WSPLGEN_POLYGONS_SHAPE);
514
515 if (!test.exists() || !test.canRead()) {
516 logger.debug("No barrier line layer existing.");
517 return;
518 }
519
520 LayerInfo polygonInfo = new LayerInfo();
521 polygonInfo.setName(MS_POLYGONS_PREFIX + uuid);
522 polygonInfo.setType("POLYGON");
523 polygonInfo.setDirectory(uuid);
524 polygonInfo.setData(WSPLGEN_POLYGONS_SHAPE);
525 polygonInfo.setTitle("I18N_POLYGON_SHAPE");
526 polygonInfo.setGroup(group);
527 polygonInfo.setGroupTitle(groupTitle);
528 polygonInfo.setSrid(wms.getSrid());
529
530 String namePolygons = MS_LAYER_PREFIX + wms.getName() + "-polygons";
531
532 Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
533 if (tpl == null) {
534 logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
535 return;
536 }
537
538 try {
539 writeLayer(polygonInfo, dir, namePolygons, tpl);
540 }
541 catch (FileNotFoundException fnfe) {
542 logger.error(fnfe, fnfe);
543 logger.warn("Unable to write layer: " + namePolygons);
544 }
545 }
546
547
548 /**
549 * Creates a layer file used for Mapserver's mapfile which represents the
550 * shape files uploaded by the user.
551 *
552 * @param flys The FLYSArtifact that owns <i>wms</i>.
553 * @param wms The WMSLayerFacet that contains information for the layer.
554 */
555 public void createUserShapeLayer(FLYSArtifact flys, WMSLayerFacet wms)
556 throws FileNotFoundException, IOException
557 {
558 logger.debug("createUserShapeLayer");
559
560 String uuid = flys.identifier();
561 File dir = new File(getShapefileBaseDir(), uuid);
562 File test = new File(dir, WSPLGEN_USER_SHAPE);
563
564 if (!test.exists() || !test.canRead()) {
565 logger.debug("No user layer existing.");
566 return;
567 }
568
569 File userShape = new File(dir, WSPLGEN_USER_SHAPE);
570 ShpFiles sf = new ShpFiles(userShape);
571 ShapefileReader sfr = new ShapefileReader(sf, true, false, null);
572 ShapefileHeader sfh = sfr.getHeader();
573
574 String group = uuid + MS_USERSHAPE_PREFIX;
575 String groupTitle = "I18N_USER_SHAPE_TITLE";
576
577 LayerInfo info = new LayerInfo();
578 info.setName(MS_USERSHAPE_PREFIX + uuid);
579 if (sfh.getShapeType().isLineType()) {
580 info.setType("LINE");
581 }
582 else if (sfh.getShapeType().isPolygonType()) {
583 info.setType("POLYGON");
584 }
585 else {
586 return;
587 }
588 info.setDirectory(uuid);
589 info.setData(WSPLGEN_USER_SHAPE);
590 info.setTitle("I18N_USER_SHAPE");
591 info.setGroup(group);
592 info.setGroupTitle(groupTitle);
593 info.setSrid(wms.getSrid());
594
595 String nameUser = MS_LAYER_PREFIX + wms.getName();
596
597 Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
598 if (tpl == null) {
599 logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
600 return;
601 }
602
603 try {
604 writeLayer(info, dir, nameUser, tpl);
605 }
606 catch (FileNotFoundException fnfe) {
607 logger.error(fnfe, fnfe);
608 logger.warn("Unable to write layer: " + nameUser);
609 }
610
611 }
612
613
614 /**
615 * Creates a layer file used for Mapserver's mapfile which represents
616 * geometries from database.
617 *
618 * @param flys The FLYSArtifact that owns <i>wms</i>.
619 * @param wms The WMSLayerFacet that contains information for the layer.
620 */
621 public void createDatabaseLayer(
622 FLYSArtifact flys,
623 WMSDBLayerFacet wms,
624 String style
625 )
626 throws FileNotFoundException, IOException
627 {
628 logger.debug("createDatabaseLayer");
629
630 LayerInfo layerinfo = new LayerInfo();
631 layerinfo.setName(wms.getName() + "-" + flys.identifier());
632 layerinfo.setType(wms.getGeometryType());
633 layerinfo.setFilter(wms.getFilter());
634 layerinfo.setData(wms.getData());
635 layerinfo.setTitle(wms.getDescription());
636 layerinfo.setStyle(style);
637 if(wms.getExtent() != null) {
638 layerinfo.setExtent(GeometryUtils.jtsBoundsToOLBounds(wms.getExtent()));
639 }
640 layerinfo.setConnection(wms.getConnection());
641 layerinfo.setConnectionType(wms.getConnectionType());
642 layerinfo.setLabelItem(wms.getLabelItem());
643 layerinfo.setSrid(wms.getSrid());
644
645 String name = MS_LAYER_PREFIX + wms.getName();
646
647 Template template = getTemplateByName(DB_LAYER_TEMPLATE);
648 if (template == null) {
649 logger.warn("Template '" + DB_LAYER_TEMPLATE + "' found.");
650 return;
651 }
652
653 try {
654 File dir = new File(getShapefileBaseDir(), flys.identifier());
655 writeLayer(layerinfo, dir, name, template);
656 }
657 catch (FileNotFoundException fnfe) {
658 logger.error(fnfe, fnfe);
659 logger.warn("Unable to write layer: " + name);
660 }
661 }
662 260
663 261
664 /** 262 /**
665 * Creates a layer snippet which might be included in the mapfile. 263 * Creates a layer snippet which might be included in the mapfile.
666 * 264 *

http://dive4elements.wald.intevation.org