1 package fr.ifremer.dali.ui.swing.content.home.map;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.vividsolutions.jts.geom.Geometry;
25 import com.vividsolutions.jts.geom.Point;
26 import fr.ifremer.dali.config.DaliConfiguration;
27 import fr.ifremer.dali.dao.technical.Geometries;
28 import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
29 import fr.ifremer.dali.dto.data.survey.SurveyDTO;
30 import fr.ifremer.dali.dto.referential.LocationDTO;
31 import fr.ifremer.dali.map.*;
32 import fr.ifremer.dali.service.DaliTechnicalException;
33 import fr.ifremer.dali.ui.swing.util.map.MapBuilder;
34 import fr.ifremer.dali.ui.swing.util.map.layer.*;
35 import fr.ifremer.dali.ui.swing.util.map.layer.tile.MapTileLayer;
36 import fr.ifremer.dali.ui.swing.util.map.layer.wms.GraticuleWMSLayer;
37 import fr.ifremer.dali.ui.swing.util.map.layer.wms.WMSMapLayer;
38 import fr.ifremer.quadrige3.core.dao.technical.Assert;
39 import fr.ifremer.quadrige3.core.dao.technical.Dates;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.geotools.data.FileDataStore;
43 import org.geotools.data.FileDataStoreFinder;
44 import org.geotools.data.collection.CollectionFeatureSource;
45 import org.geotools.data.ows.CRSEnvelope;
46 import org.geotools.data.ows.WMSCapabilities;
47 import org.geotools.data.simple.SimpleFeatureSource;
48 import org.geotools.data.wms.WMSUtils;
49 import org.geotools.data.wmts.client.WMTSTileService;
50 import org.geotools.data.wmts.model.WMTSCapabilities;
51 import org.geotools.data.wmts.model.WMTSLayer;
52 import org.geotools.factory.CommonFactoryFinder;
53 import org.geotools.feature.DefaultFeatureCollection;
54 import org.geotools.feature.simple.SimpleFeatureBuilder;
55 import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
56 import org.geotools.geometry.jts.ReferencedEnvelope;
57 import org.geotools.map.Layer;
58 import org.geotools.map.MapContent;
59 import org.geotools.map.WMSLayer;
60 import org.geotools.ows.ServiceException;
61 import org.geotools.referencing.CRS;
62 import org.geotools.referencing.crs.DefaultGeographicCRS;
63 import org.geotools.styling.*;
64 import org.opengis.feature.simple.SimpleFeature;
65 import org.opengis.feature.simple.SimpleFeatureType;
66 import org.opengis.filter.Filter;
67 import org.opengis.filter.FilterFactory2;
68 import org.opengis.geometry.BoundingBox;
69 import org.opengis.referencing.FactoryException;
70 import org.opengis.referencing.crs.CRSAuthorityFactory;
71 import org.opengis.referencing.crs.CoordinateReferenceSystem;
72
73 import javax.swing.UIManager;
74 import java.awt.Color;
75 import java.io.IOException;
76 import java.net.URL;
77 import java.util.*;
78
79 import static org.nuiton.i18n.I18n.t;
80
81
82
83
84
85
86
87 public class SurveysMapBuilder implements MapBuilder {
88
89 private static final Log LOG = LogFactory.getLog(SurveysMapBuilder.class);
90
91
92 private final DaliConfiguration configuration;
93
94 private MapMode currentMapMode;
95 private CoordinateReferenceSystem targetCRS;
96
97
98 private static final String GEOMETRY = "geometry";
99 private static final String LABEL = "label";
100 private static final String POINT_TYPE = "pointType";
101 private static final String POINT_TYPE_START = "pointTypeStart";
102 private static final String POINT_TYPE_END = "pointTypeEnd";
103 private static final String INTERNAL = "internal";
104 private static final String LOCATION_LAYER_NAME_PREFIX = "location_";
105 private static final String SURVEY_LAYER_NAME_PREFIX = "survey_";
106 private static final String OPERATION_LAYER_NAME_PREFIX = "operation_";
107 private static final String LAYER_NAME_SUFFIX = "_Layer";
108 private static final String POINT_LAYER_NAME_SUFFIX = "_PointLayer";
109 private static final String LINE_LAYER_NAME_SUFFIX = "_LineLayer";
110
111
112 private static final String SHAPE_FILE_EXTENSION = ".shp";
113 private static final String SHAPE_RESOURCE_DIRECTORY = "shapes";
114
115
116
117
118
119
120
121
122 private static StyleBuilder SB = new StyleBuilder();
123 private static StyleFactory SF = CommonFactoryFinder.getStyleFactory(null);
124 private static FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2(null);
125
126
127 private SimpleFeatureType locationFeatureType;
128 private SimpleFeatureType surveyFeatureType;
129 private SimpleFeatureType operationFeatureType;
130
131 private static Color colorEarth = Color.decode("#8C8C8C");
132 private static Color colorWater = Color.decode("#B6EDF0");
133
134 private static Fill fillBlack = SF.createFill(FF.literal(Color.BLACK));
135 private static Stroke strokeBlack = SF.createStroke(FF.literal(Color.BLACK), FF.literal(1.0f));
136 private static Halo haloWhite = SB.createHalo(Color.WHITE, 3);
137
138 private static PointPlacement middleTopPlacement = SB.createPointPlacement(SB.createAnchorPoint(0.5, 0), SB.createDisplacement(0, 10), SB.literalExpression(0));
139 private static LinePlacement labelLinePlacement = SB.createLinePlacement(16);
140
141 private Style styleLocationPoint;
142 private Style styleLocationLine;
143 private Style styleLocationPolygon;
144 private Style styleSurveyPoint;
145 private Style styleSurveyLine;
146 private Style styleSurveyLinePoints;
147 private Style styleOperationPoint;
148
149 public SurveysMapBuilder(DaliConfiguration configuration) {
150 this.configuration = configuration;
151 init();
152 }
153
154 public static void main(String... args) {
155
156 SurveysMapBuilder mapBuilder = new SurveysMapBuilder(null);
157 mapBuilder.buildNewMapContent(MapMode.EMBEDDED_SHAPE_MAP_MODE);
158 }
159
160 private void init() {
161
162
163 {
164
165 SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
166 typeBuilder.setName("locationFeatureType");
167 typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
168 typeBuilder.setDefaultGeometry(GEOMETRY);
169 typeBuilder.add(GEOMETRY, Geometry.class);
170 typeBuilder.add(LABEL, String.class);
171 locationFeatureType = typeBuilder.buildFeatureType();
172 }
173 {
174
175 SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
176 typeBuilder.setName("surveyFeatureType");
177 typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
178 typeBuilder.setDefaultGeometry(GEOMETRY);
179 typeBuilder.add(GEOMETRY, Geometry.class);
180 typeBuilder.add(LABEL, String.class);
181 typeBuilder.add(POINT_TYPE, String.class);
182 surveyFeatureType = typeBuilder.buildFeatureType();
183 }
184 {
185
186 SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
187 typeBuilder.setName("operationFeatureType");
188 typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
189 typeBuilder.setDefaultGeometry(GEOMETRY);
190 typeBuilder.add(GEOMETRY, Geometry.class);
191 typeBuilder.add(LABEL, String.class);
192 operationFeatureType = typeBuilder.buildFeatureType();
193 }
194
195
196 java.awt.Font uiFont = UIManager.getFont("Label.font");
197 Font font;
198 if (uiFont != null) {
199 font = SF.createFont(FF.literal(uiFont.getFamily()), FF.literal("normal"), FF.literal("bold"), FF.literal(uiFont.getSize()));
200 } else {
201 font = SF.getDefaultFont();
202 font.setSize(FF.literal(14));
203 }
204
205
206 {
207
208 Color color = Color.BLUE;
209 Stroke stroke = SF.createStroke(FF.literal(color), FF.literal(1.0f));
210 Fill fill = SF.createFill(FF.literal(color.brighter().brighter()), FF.literal(.5f));
211
212 Mark mark = SF.createMark(FF.literal(StyleBuilder.MARK_CIRCLE), stroke, fill, null, null);
213 Graphic graphic = SF.createDefaultGraphic();
214 graphic.graphicalSymbols().clear();
215 graphic.graphicalSymbols().add(mark);
216 graphic.setSize(FF.literal(10));
217
218
219 TextSymbolizer textPointSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), middleTopPlacement, null);
220 textPointSymbolizer.setPriority(FF.literal(1));
221 styleLocationPoint = createStyle(
222 "styleLocationPoint",
223 createPointSymbolizer("symbolizerLocationPoint", graphic),
224 textPointSymbolizer);
225
226
227 TextSymbolizer textLineSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), labelLinePlacement, null);
228 textLineSymbolizer.setPriority(FF.literal(1));
229
230 styleLocationLine = createStyle(
231 "styleLocationLine",
232 textLineSymbolizer,
233 createLineSymbolizer("symbolizerLocationLine", stroke));
234
235
236 TextSymbolizer textPolygonSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), middleTopPlacement, null);
237 textPolygonSymbolizer.setPriority(FF.literal(1));
238 textPolygonSymbolizer.getOptions().put(TextSymbolizer.GOODNESS_OF_FIT_KEY, String.valueOf(0.0d));
239 styleLocationPolygon = createStyle(
240 "styleLocationPolygon",
241 createPolygonSymbolizer("symbolizerLocationPolygon", stroke, fill),
242 textPolygonSymbolizer);
243
244 }
245
246 {
247
248 Color colorLine = Color.GREEN;
249 Color colorPoint = Color.BLUE;
250 Color colorStart = Color.GREEN;
251 Color colorEnd = Color.RED;
252 Stroke stroke = SF.createStroke(FF.literal(colorLine), FF.literal(3));
253 Fill fillPoint = SF.createFill(FF.literal(colorPoint), FF.literal(1.0f));
254 Fill fillStart = SF.createFill(FF.literal(colorStart), FF.literal(1.0f));
255 Fill fillEnd = SF.createFill(FF.literal(colorEnd), FF.literal(1.0f));
256
257
258 TextSymbolizer textSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), labelLinePlacement, null);
259 textSymbolizer.setPriority(FF.literal(2));
260 styleSurveyLine = createStyle(
261 "styleSurveyLine",
262 createLineSymbolizer("symbolizerSurveyLine", stroke),
263 textSymbolizer);
264
265
266
267
268 Mark markStart = SF.createMark(FF.literal(StyleBuilder.MARK_TRIANGLE), strokeBlack, fillStart, null, null);
269 Graphic graphicStart = SF.createDefaultGraphic();
270 graphicStart.graphicalSymbols().clear();
271 graphicStart.graphicalSymbols().add(markStart);
272 graphicStart.setSize(FF.literal(10));
273 Symbolizer pointSymbolizerStart = createPointSymbolizer("symbolizerSurveyPointStart", graphicStart);
274
275
276 Mark markEnd = SF.createMark(FF.literal(StyleBuilder.MARK_X), strokeBlack, fillEnd, null, null);
277 Graphic graphicEnd = SF.createDefaultGraphic();
278 graphicEnd.graphicalSymbols().clear();
279 graphicEnd.graphicalSymbols().add(markEnd);
280 graphicEnd.setSize(FF.literal(10));
281 Symbolizer pointSymbolizerEnd = createPointSymbolizer("symbolizerSurveyPointEnd", graphicEnd);
282
283
284 Rule ruleStart = SB.createRule(pointSymbolizerStart);
285 Filter filterStart = SB.getFilterFactory().equals(FF.property(POINT_TYPE), FF.literal(POINT_TYPE_START));
286 ruleStart.setFilter(filterStart);
287
288 Rule ruleEnd = SB.createRule(pointSymbolizerEnd);
289 Filter filterEnd = SB.getFilterFactory().equals(FF.property(POINT_TYPE), FF.literal(POINT_TYPE_END));
290 ruleEnd.setFilter(filterEnd);
291
292
293 styleSurveyLinePoints = createStyle("styleSurveyLinePoints", ruleStart, ruleEnd);
294
295
296 TextSymbolizer textPointSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), middleTopPlacement, null);
297 textPointSymbolizer.setPriority(FF.literal(2));
298 Mark markPoint = SF.createMark(FF.literal(StyleBuilder.MARK_TRIANGLE), strokeBlack, fillPoint, null, null);
299 Graphic graphicPoint = SF.createDefaultGraphic();
300 graphicPoint.graphicalSymbols().clear();
301 graphicPoint.graphicalSymbols().add(markPoint);
302 graphicPoint.setSize(FF.literal(10));
303
304 styleSurveyPoint = createStyle("styleSurveyPoint", createPointSymbolizer("symbolizerSurveyPoint", graphicPoint), textPointSymbolizer);
305 }
306
307 {
308
309 Color color = Color.YELLOW;
310 Fill fill = SF.createFill(FF.literal(color.brighter().brighter()), FF.literal(1.0f));
311
312 Mark mark = SF.createMark(FF.literal(StyleBuilder.MARK_SQUARE), strokeBlack, fill, null, null);
313 Graphic graphic = SF.createDefaultGraphic();
314 graphic.graphicalSymbols().clear();
315 graphic.graphicalSymbols().add(mark);
316 graphic.setSize(FF.literal(10));
317
318 TextSymbolizer textSymbolizer = SF.createTextSymbolizer(fillBlack, new Font[]{font}, haloWhite, FF.property(LABEL), middleTopPlacement, null);
319 textSymbolizer.setPriority(FF.literal(3));
320 styleOperationPoint = createStyle("styleOperationPoint", createPointSymbolizer("symbolizerOperationPoint", graphic), textSymbolizer);
321
322
323 }
324 }
325
326 @Override
327 public MapContent buildNewMapContent(MapMode preferredMode) {
328
329 MapContent mapContent = new MapContent();
330
331 try {
332
333 currentMapMode = Optional.ofNullable(preferredMode).orElse(configuration.getPreferredMapMode());
334 if (currentMapMode == null) {
335 throw new DaliTechnicalException("Unable to determine map mode");
336 }
337
338 MapConfiguration mapConfiguration = currentMapMode.getMapConfiguration();
339
340 if (mapConfiguration.isOnline()) {
341
342
343 if (!Maps.isMapServerReachable(currentMapMode)) return buildNewMapContent(getFirstOfflineMode());
344
345 if (mapConfiguration instanceof WMSMapConfiguration) {
346
347
348 WMSCapabilities wmsCapabilities = ((WMSMapConfiguration) mapConfiguration).getCapabilities();
349 org.geotools.data.ows.Layer[] layers = WMSUtils.getNamedLayers(wmsCapabilities);
350
351
352 for (MapLayerDefinition layerDefinition : currentMapMode.getMapLayerDefinitions()) {
353 for (org.geotools.data.ows.Layer layer : layers) {
354 if (layerDefinition.getName().equals(layer.getName())) {
355
356 WMSLayer wmsLayer;
357 if (layerDefinition instanceof GraticuleLayerDefinition) {
358 wmsLayer = new GraticuleWMSLayer(((WMSMapConfiguration) mapConfiguration).getWebService(), layer);
359 } else {
360 wmsLayer = new WMSMapLayer(((WMSMapConfiguration) mapConfiguration).getWebService(), layer);
361 }
362 wmsLayer.setTitle(layer.getName());
363
364 mapContent.addLayer(wmsLayer);
365 }
366 }
367 }
368 mapContent.addLayer(new ScaleLayer());
369
370 } else if (mapConfiguration instanceof WMTSMapConfiguration) {
371
372 WMTSCapabilities wmtsCapabilities = ((WMTSMapConfiguration) mapConfiguration).getCapabilities();
373 WMTSLayer layer = wmtsCapabilities.getLayer(currentMapMode.getBaseLayerName());
374
375
376
377 CRSEnvelope limitEnvelope = new CRSEnvelope(configuration.getMapProjection().getEnvelope());
378 layer.setBoundingBoxes(limitEnvelope);
379 layer.setLatLonBoundingBox(limitEnvelope);
380
381 WMTSTileService service = new WMTSTileService(
382 currentMapMode.getUrl(),
383 wmtsCapabilities.getType(),
384 layer,
385 "",
386 wmtsCapabilities.getMatrixSet(configuration.getMapProjection().getCode()));
387
388
389
390 mapContent.addLayer(new MapTileLayer(service, currentMapMode.getBaseLayerName()));
391
392
393 mapContent.addLayer(new GraticuleDirectLayer());
394 mapContent.addLayer(new ScaleLayer());
395
396 } else if (mapConfiguration instanceof OSMBasedMapConfiguration) {
397
398
399 mapContent.addLayer(new MapTileLayer(((OSMBasedMapConfiguration) mapConfiguration).getTileService(), currentMapMode.getBaseLayerName()));
400
401
402 mapContent.addLayer(new GraticuleDirectLayer());
403 mapContent.addLayer(new ScaleLayer());
404
405 }
406
407 } else {
408
409
410 for (MapLayerDefinition layerDefinition : currentMapMode.getMapLayerDefinitions()) {
411 Layer layer = newMapLayer(layerDefinition.getName(), colorEarth.darker(), 2, colorEarth, 1f);
412 mapContent.addLayer(layer);
413 }
414
415
416 mapContent.addLayer(new GraticuleDirectLayer());
417 mapContent.addLayer(new ScaleLayer());
418
419 }
420
421
422 CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
423 MapProjection targetProjection = configuration.getMapProjection();
424
425
426
427
428
429 targetCRS = factory.createCoordinateReferenceSystem(targetProjection.getCode());
430 mapContent.getViewport().setCoordinateReferenceSystem(targetCRS);
431
432 } catch (IOException | ServiceException | FactoryException e) {
433 throw new DaliTechnicalException(e);
434 }
435
436 return mapContent;
437 }
438
439 @Override
440 public CoordinateReferenceSystem getTargetCRS() {
441 return targetCRS;
442 }
443
444 @Override
445 public MapMode getCurrentMapMode() {
446 if (currentMapMode == null) currentMapMode = configuration.getPreferredMapMode();
447 return currentMapMode;
448 }
449
450 @Override
451 public boolean checkOnlineReachable() {
452 return Maps.isMapServerReachable(getCurrentMapMode())
453 || Maps.isMapServerReachable(configuration.getPreferredMapMode());
454 }
455
456 @Override
457 public Color getBackgroundColor() {
458 return colorWater;
459 }
460
461 private MapMode getFirstOfflineMode() {
462 return Arrays.stream(MapMode.values()).filter(mapMode -> !mapMode.isOnline()).findFirst().orElse(null);
463 }
464
465 private Layer newMapLayer(String shapeName, Color outlineColor, int outlineWidth, Color fillColor, float fillOpacity) throws IOException {
466
467 FileDataStore store = FileDataStoreFinder.getDataStore(getShapeURL(shapeName));
468 SimpleFeatureSource source = store.getFeatureSource();
469
470 Stroke stroke = SF.createStroke(FF.literal(outlineColor), FF.literal(outlineWidth));
471 Fill fill = Fill.NULL;
472 if (fillColor != null) {
473 fill = SF.createFill(FF.literal(fillColor), FF.literal(fillOpacity));
474 }
475
476 Style style = createStyle("styleMapPolygon", createPolygonSymbolizer("symbolizerMapPolygon", stroke, fill));
477 return new MapFeatureLayer(source, style, shapeName);
478
479 }
480
481 private URL getShapeURL(String shapeName) {
482
483 Assert.notNull(shapeName);
484 if (!shapeName.endsWith(SHAPE_FILE_EXTENSION)) shapeName += SHAPE_FILE_EXTENSION;
485
486
487 URL shapeUrl = SurveysMapUIHandler.class.getResource(String.format("/%s/%s", SHAPE_RESOURCE_DIRECTORY, shapeName));
488 if (shapeUrl == null) {
489 throw new DaliTechnicalException(shapeName + " not found");
490 }
491 return shapeUrl;
492 }
493
494
495
496
497
498
499
500 @Override
501 public DataLayerCollection buildDataLayerCollection(Object dataObject) {
502
503 Assert.notNull(dataObject);
504 Assert.isInstanceOf(SurveyDTO.class, dataObject);
505
506 SurveyDTO survey = (SurveyDTO) dataObject;
507
508 SurveyLayerCollection dataLayerCollection = new SurveyLayerCollection();
509
510
511 LocationDTO location = survey.getLocation();
512 if (Geometries.isValid(location.getCoordinate())) {
513
514 Geometry geometry = Geometries.getGeometry(location.getCoordinate().getWkt());
515 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(locationFeatureType);
516 builder.add(geometry);
517 builder.add(location.getName());
518 SimpleFeature feature = builder.buildFeature(location.getId().toString());
519 DefaultFeatureCollection collection = new DefaultFeatureCollection(INTERNAL, locationFeatureType);
520 collection.add(feature);
521 SimpleFeatureSource source = new CollectionFeatureSource(collection);
522
523 int dimension = geometry.getDimension();
524 Style style = dimension == 2 ? styleLocationPolygon : dimension == 1 ? styleLocationLine : styleLocationPoint;
525
526 dataLayerCollection.setLocationLayer(
527 new DataFeatureLayer(dataLayerCollection, location.getId(), source, style, LOCATION_LAYER_NAME_PREFIX + location.getId() + LAYER_NAME_SUFFIX));
528 }
529
530
531 if (Geometries.isValid(survey.getCoordinate())) {
532
533 DataFeatureLayer layerLine = null;
534 DataFeatureLayer layerPoint;
535
536 if (Geometries.isPoint(survey.getCoordinate())) {
537
538 Point pointStart = Geometries.createPoint(survey.getCoordinate().getMinLongitude(), survey.getCoordinate().getMinLatitude());
539 DefaultFeatureCollection collection = new DefaultFeatureCollection(INTERNAL, surveyFeatureType);
540 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(surveyFeatureType);
541 builder.add(pointStart);
542 builder.add(getSurveyGeometryLabel(survey));
543 builder.add(POINT_TYPE_START);
544 collection.add(builder.buildFeature(POINT_TYPE_START + "_" + survey.getId().toString()));
545 SimpleFeatureSource source = new CollectionFeatureSource(collection);
546 layerPoint = new DataFeatureLayer(dataLayerCollection, survey.getId(), source, styleSurveyPoint, SURVEY_LAYER_NAME_PREFIX + survey.getId().toString() + POINT_LAYER_NAME_SUFFIX);
547
548 } else {
549 {
550
551 Geometry geometry = Geometries.getGeometry(survey.getCoordinate());
552 DefaultFeatureCollection collection = new DefaultFeatureCollection(INTERNAL, surveyFeatureType);
553 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(surveyFeatureType);
554 builder.add(geometry);
555 builder.add(getSurveyGeometryLabel(survey));
556 collection.add(builder.buildFeature(survey.getId().toString()));
557 SimpleFeatureSource source = new CollectionFeatureSource(collection);
558 layerLine = new DataFeatureLayer(dataLayerCollection, survey.getId(), source, styleSurveyLine, SURVEY_LAYER_NAME_PREFIX + survey.getId().toString() + LINE_LAYER_NAME_SUFFIX);
559 }
560 {
561
562 Point pointStart = Geometries.createPoint(survey.getCoordinate().getMinLongitude(), survey.getCoordinate().getMinLatitude());
563 Point pointEnd = Geometries.createPoint(survey.getCoordinate().getMaxLongitude(), survey.getCoordinate().getMaxLatitude());
564 DefaultFeatureCollection collection = new DefaultFeatureCollection(INTERNAL, surveyFeatureType);
565 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(surveyFeatureType);
566 builder.add(pointStart);
567 builder.add(null);
568 builder.add(POINT_TYPE_START);
569 collection.add(builder.buildFeature(POINT_TYPE_START + "_" + survey.getId().toString()));
570 builder = new SimpleFeatureBuilder(surveyFeatureType);
571 builder.add(pointEnd);
572 builder.add(null);
573 builder.add(POINT_TYPE_END);
574 collection.add(builder.buildFeature(POINT_TYPE_END + "_" + survey.getId().toString()));
575 SimpleFeatureSource source = new CollectionFeatureSource(collection);
576 layerPoint = new DataFeatureLayer(dataLayerCollection, survey.getId(), source, styleSurveyLinePoints, SURVEY_LAYER_NAME_PREFIX + survey.getId().toString() + POINT_LAYER_NAME_SUFFIX);
577 }
578 }
579
580 dataLayerCollection.setSurveyLayer(layerLine, layerPoint);
581
582 }
583
584
585 if (!survey.isSamplingOperationsEmpty()) {
586 for (SamplingOperationDTO operation : survey.getSamplingOperations()) {
587
588 if (Geometries.isValid(operation.getCoordinate())) {
589
590 Point point = Geometries.createPoint(operation.getCoordinate().getMinLongitude(), operation.getCoordinate().getMinLatitude());
591 DefaultFeatureCollection collection = new DefaultFeatureCollection(INTERNAL, operationFeatureType);
592 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(operationFeatureType);
593 builder.add(point);
594 builder.add(getOperationGeometryLabel(operation));
595 collection.add(builder.buildFeature(operation.getId().toString()));
596 SimpleFeatureSource source = new CollectionFeatureSource(collection);
597
598 dataLayerCollection.addOperationLayer(
599 null,
600 new DataFeatureLayer(dataLayerCollection, operation.getId(), source, styleOperationPoint, OPERATION_LAYER_NAME_PREFIX + operation.getId().toString() + POINT_LAYER_NAME_SUFFIX));
601 }
602 }
603 }
604
605 return dataLayerCollection;
606 }
607
608 private String getSurveyGeometryLabel(SurveyDTO survey) {
609 return survey.getName() + " - " + Dates.formatDate(survey.getDate(), configuration.getDateFormat());
610 }
611
612 private String getOperationGeometryLabel(SamplingOperationDTO operation) {
613 return operation.getName();
614 }
615
616 private Symbolizer createPolygonSymbolizer(String name, Stroke stroke, Fill fill) {
617 return createNamedSymbolizer(name, SF.createPolygonSymbolizer(stroke, fill, null));
618 }
619
620 private Symbolizer createLineSymbolizer(String name, Stroke stroke) {
621 return createNamedSymbolizer(name, SF.createLineSymbolizer(stroke, null));
622 }
623
624 private Symbolizer createPointSymbolizer(String name, Graphic graphic) {
625 return createNamedSymbolizer(name, SF.createPointSymbolizer(graphic, null));
626 }
627
628 private Symbolizer createNamedSymbolizer(String name, Symbolizer symbolizer) {
629 symbolizer.setName(name);
630 String title = "dali.home.map.legend." + name;
631 if (symbolizer.getDescription() == null) symbolizer.setDescription(new DescriptionImpl());
632 symbolizer.getDescription().setTitle(t(title));
633 return symbolizer;
634 }
635
636 private Style createStyle(String name, Symbolizer... symbolizers) {
637
638 Rule rule = SF.createRule();
639
640 if (symbolizers != null) {
641 for (Symbolizer sym : symbolizers) {
642 rule.symbolizers().add(sym);
643 }
644 }
645
646 return createStyle(name, rule);
647 }
648
649 private Style createStyle(String name, Rule... rules) {
650 Style style = SF.createStyle();
651 style.featureTypeStyles().add(SF.createFeatureTypeStyle(rules));
652 style.setName(name);
653 return style;
654 }
655
656
657
658
659
660
661
662
663
664 @Override
665 public List<String> getDisplayableLayerNames(ReferencedEnvelope displayArea) {
666
667 List<String> layerNames = new ArrayList<>();
668 String defaultLayerName = null;
669 boolean addDefaultLayer = true;
670 boolean allowAddLayer = true;
671
672 List<MapLayerDefinition> layers = new ArrayList<>(currentMapMode.getMapLayerDefinitions());
673
674 displayArea = Maps.transformReferencedEnvelope(displayArea, DefaultGeographicCRS.WGS84);
675
676
677 Collections.reverse(layers);
678 for (MapLayerDefinition layerDefinition : layers) {
679
680
681 if (layerDefinition.isDefaultLayer()) {
682 defaultLayerName = layerDefinition.getName();
683 } else {
684
685
686 if (layerDefinition.isGlobalLayer()) {
687 layerNames.add(layerDefinition.getName());
688 }
689
690
691 else if (allowAddLayer && layerDefinition.getViewEnvelope().contains((BoundingBox) displayArea)) {
692
693
694 layerNames.add(layerDefinition.getName());
695
696
697 allowAddLayer = layerDefinition.isAllowOverlap();
698
699
700 addDefaultLayer = false;
701 }
702 }
703 }
704
705 if (addDefaultLayer && defaultLayerName != null) {
706 layerNames.add(defaultLayerName);
707 }
708 return layerNames;
709 }
710
711 public static boolean isLocationLayer(DataFeatureLayer layer) {
712 return layer != null && layer.getTitle() != null && layer.getTitle().startsWith(LOCATION_LAYER_NAME_PREFIX);
713 }
714
715 public static boolean isSurveyLayer(DataFeatureLayer layer) {
716 return layer != null && layer.getTitle() != null && layer.getTitle().startsWith(SURVEY_LAYER_NAME_PREFIX);
717 }
718
719 public static boolean isOperationLayer(DataFeatureLayer layer) {
720 return layer != null && layer.getTitle() != null && layer.getTitle().startsWith(OPERATION_LAYER_NAME_PREFIX);
721 }
722 }