All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.ird.observe.client.util.tripMap.TripMapContentBuilder Maven / Gradle / Ivy

package fr.ird.observe.client.util.tripMap;

/*
 * #%L
 * ObServe Toolkit :: Common Client
 * %%
 * Copyright (C) 2008 - 2017 IRD, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import fr.ird.observe.client.ObserveClientTechnicalException;
import fr.ird.observe.dto.data.TripMapPoint;
import fr.ird.observe.dto.data.TripMapPointType;
import fr.ird.observe.dto.decoration.ObserveI18nDecoratorHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.referencing.CRS;
import org.geotools.styling.NamedLayer;
import org.geotools.styling.SLD;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.UserLayer;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;


import static org.nuiton.i18n.I18n.t;

/**
 * @author Tony Chemit - [email protected]
 */
public class TripMapContentBuilder {

    public static final String TRIP_LINES_LAYER_NAME = "Trip lines";
    public static final String TRIP_LONGLINE_FISHING_ZONE_LAYER_NAME = "Trip longline zone";
    public static final String TRIP_LONGLINE_LINE_LAYER_NAME = "Trip longline line";
    public static final String TRIP_POINTS_LAYER_NAME = "Trip points";

    protected static final Set TRIP_MAP_POINT_TYPES_IN_LEGEND = ImmutableSet.of(
            TripMapPointType.seineActivityInHarbour,
            TripMapPointType.seineActivityWithFreeSchoolType,
            TripMapPointType.seineActivityWithObjectSchoolType,
            TripMapPointType.longlineActivityInHarbour,
            TripMapPointType.longlineActivityWithSettingStart,
            TripMapPointType.longlineActivityWithSettingEnd,
            TripMapPointType.longlineActivityWithHaulingStart,
            TripMapPointType.longlineActivityWithHaulingEnd,
            TripMapPointType.longlineActivityWithStation,
            TripMapPointType.longlineActivityWithInteraction);

    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM");

    protected StyledLayerDescriptor styledLayerDescriptor;
    protected final MapContent mapContent;
    protected final List legendItems;

    public TripMapContentBuilder() {
        mapContent = new MapContent();
        legendItems = Lists.newArrayList();
    }

    public MapContent getMapContent() {
        return mapContent;
    }

    public List getLegendItems() {
        return legendItems;
    }

    public void setStyledLayerDescriptor(File styleFile) throws FileNotFoundException {

        StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null);

        SLDParser stylereader = new SLDParser(styleFactory, styleFile);

        styledLayerDescriptor = stylereader.parseSLD();
    }

    public void addLayer(File layerFile) throws IOException {
        FileDataStore store = FileDataStoreFinder.getDataStore(layerFile);
        SimpleFeatureSource featureSource = store.getFeatureSource();
        Style style = SLD.createSimpleStyle(featureSource.getSchema());
        style = findStyle(styledLayerDescriptor, store.getNames().get(0).getLocalPart(), null, style);
        Layer layer = new FeatureLayer(featureSource, style, layerFile.getName());
        mapContent.addLayer(layer);
    }

    public void addTripLine(List tripMapPoints) throws FactoryException {

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

        SimpleFeatureTypeBuilder lineFeatureTypeBuilder = new SimpleFeatureTypeBuilder();
        lineFeatureTypeBuilder.setName("lineBuilder");
        lineFeatureTypeBuilder.setCRS(CRS.decode("EPSG:4326", true));
        lineFeatureTypeBuilder.add("line", LineString.class);
        lineFeatureTypeBuilder.add("label", String.class);
        lineFeatureTypeBuilder.add("type", String.class);

        SimpleFeatureType lineFeatureType = lineFeatureTypeBuilder.buildFeatureType();
        SimpleFeatureBuilder lineBuilder = new SimpleFeatureBuilder(lineFeatureType);

        DefaultFeatureCollection linesFeatures = new DefaultFeatureCollection();

        List coordinatesByDay = null;

        TripMapPoint previousPoint = null;

        for (TripMapPoint point : tripMapPoints) {
            if (previousPoint == null) {
                coordinatesByDay = Lists.newLinkedList();
            } else if (!DateUtils.isSameDay(previousPoint.getTime(), point.getTime())) {

                if (coordinatesByDay.size() > 1) {
                    LineString line = geometryFactory.createLineString(coordinatesByDay.toArray(new Coordinate[0]));
                    lineBuilder.add(line);
                    lineBuilder.add(DATE_FORMAT.format(previousPoint.getTime()));
                    lineBuilder.add("tripDay");
                    SimpleFeature feature = lineBuilder.buildFeature(null);

                    linesFeatures.add(feature);
                }


                Coordinate[] coordinates = {
                        new Coordinate(previousPoint.getLongitude(), previousPoint.getLatitude()),
                        new Coordinate(point.getLongitude(), point.getLatitude()),
                };
                LineString lineBetweenTwoDays = geometryFactory.createLineString(coordinates);
                lineBuilder.add(lineBetweenTwoDays);
                lineBuilder.add(DateFormat.getDateInstance().format(previousPoint.getTime()));
                lineBuilder.add("tripBetweenTwoDays");
                linesFeatures.add(lineBuilder.buildFeature(null));

                coordinatesByDay = Lists.newLinkedList();
            }

            Coordinate coordinate = new Coordinate(point.getLongitude(), point.getLatitude());
            coordinatesByDay.add(coordinate);

            previousPoint = point;
        }

        if (coordinatesByDay != null && coordinatesByDay.size() > 1) {
            LineString line = geometryFactory.createLineString(coordinatesByDay.toArray(new Coordinate[0]));
            lineBuilder.add(line);
            lineBuilder.add(DATE_FORMAT.format(previousPoint.getTime()));
            lineBuilder.add("tripDay");
            linesFeatures.add(lineBuilder.buildFeature(null));
        }

        Style styleLines = findStyle(styledLayerDescriptor, TRIP_LINES_LAYER_NAME, null);

        if (!linesFeatures.isEmpty()) {
            Layer layerLines = new FeatureLayer(linesFeatures, styleLines, TRIP_LINES_LAYER_NAME);
            mapContent.addLayer(layerLines);
        }


        // add line in legend
        LineString line = geometryFactory.createLineString(ObserveMapPaneLegendItem.lineCoordinates());
        lineBuilder.add(line);
        lineBuilder.add("");
        lineBuilder.add("tripDay");

        ObserveMapPaneLegendItem legendTripDay = new ObserveMapPaneLegendItem(
                lineBuilder.buildFeature(null),
                styleLines,
                t("observe.content.map.legend.tripDay"));
        legendItems.add(legendTripDay);

        lineBuilder.add(line);
        lineBuilder.add("");
        lineBuilder.add("tripBetweenTwoDays");
        ObserveMapPaneLegendItem legendTripBetweenTwoDays = new ObserveMapPaneLegendItem(
                lineBuilder.buildFeature(null),
                styleLines,
                t("observe.content.map.legend.tripBetweenTwoDays"));
        legendItems.add(legendTripBetweenTwoDays);

    }

    public void addLonglineFishingZone(List tripMapPoints) throws FactoryException {
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

        SimpleFeatureTypeBuilder polygonFeatureTypeBuilder = new SimpleFeatureTypeBuilder();
        polygonFeatureTypeBuilder.setName("longlineFishingZoneBuilder");
        polygonFeatureTypeBuilder.setCRS(CRS.decode("EPSG:4326", true));
        polygonFeatureTypeBuilder.add("zone", Polygon.class);
        polygonFeatureTypeBuilder.add("label", String.class);
        polygonFeatureTypeBuilder.add("type", String.class);

        SimpleFeatureType polygonFeatureType = polygonFeatureTypeBuilder.buildFeatureType();
        SimpleFeatureBuilder polygonBuilder = new SimpleFeatureBuilder(polygonFeatureType);

        DefaultFeatureCollection polygonsFeatures = new DefaultFeatureCollection();

        for (int indexPoint = 3; indexPoint < tripMapPoints.size(); indexPoint++) {
            if (tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithHaulingEnd)
                    && tripMapPoints.get(indexPoint - 1).getType().equals(TripMapPointType.longlineActivityWithHaulingStart)
                    && tripMapPoints.get(indexPoint - 2).getType().equals(TripMapPointType.longlineActivityWithSettingEnd)
                    && tripMapPoints.get(indexPoint - 3).getType().equals(TripMapPointType.longlineActivityWithSettingStart)) {

                Coordinate[] coordinates = {
                        new Coordinate(tripMapPoints.get(indexPoint - 3).getLongitude(), tripMapPoints.get(indexPoint - 3).getLatitude()),
                        new Coordinate(tripMapPoints.get(indexPoint - 2).getLongitude(), tripMapPoints.get(indexPoint - 2).getLatitude()),
                        new Coordinate(tripMapPoints.get(indexPoint - 1).getLongitude(), tripMapPoints.get(indexPoint - 1).getLatitude()),
                        new Coordinate(tripMapPoints.get(indexPoint).getLongitude(), tripMapPoints.get(indexPoint).getLatitude()),
                        new Coordinate(tripMapPoints.get(indexPoint - 3).getLongitude(), tripMapPoints.get(indexPoint - 3).getLatitude())
                };


                Polygon polygon = geometryFactory.createPolygon(coordinates);
                //polygon = (Polygon) polygon.convexHull(); // permet de transformer un poliqgone croisé en polygon convex
                polygonBuilder.add(polygon);
                polygonBuilder.add(DATE_FORMAT.format(tripMapPoints.get(indexPoint - 3).getTime()));
                polygonBuilder.add("longlineFishingZone");
                SimpleFeature feature = polygonBuilder.buildFeature(null);
                polygonsFeatures.add(feature);

            }
        }

        if (!polygonsFeatures.isEmpty()) {
            Style styleLines = findStyle(styledLayerDescriptor, TRIP_LONGLINE_FISHING_ZONE_LAYER_NAME, null);
            Layer layerLines = new FeatureLayer(polygonsFeatures, styleLines, TRIP_LONGLINE_FISHING_ZONE_LAYER_NAME);
            mapContent.addLayer(layerLines);
        }
    }

    public void addLonglineLine(List tripMapPoints) throws FactoryException {
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

        SimpleFeatureTypeBuilder lineFeatureTypeBuilder = new SimpleFeatureTypeBuilder();
        lineFeatureTypeBuilder.setName("longlineSettingBuilder");
        lineFeatureTypeBuilder.setCRS(CRS.decode("EPSG:4326", true));
        lineFeatureTypeBuilder.add("line", LineString.class);
        lineFeatureTypeBuilder.add("type", String.class);

        SimpleFeatureType lineFeatureType = lineFeatureTypeBuilder.buildFeatureType();
        SimpleFeatureBuilder lineBuilder = new SimpleFeatureBuilder(lineFeatureType);

        DefaultFeatureCollection linesFeatures = new DefaultFeatureCollection();

        List defaultLineCoordinates = Lists.newLinkedList();

        for (int indexPoint = 0; indexPoint < tripMapPoints.size(); indexPoint++) {
            if (indexPoint > 1 && tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithSettingEnd)
                    && tripMapPoints.get(indexPoint - 1).getType().equals(TripMapPointType.longlineActivityWithSettingStart)
                    || tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithHaulingEnd)
                    && tripMapPoints.get(indexPoint - 1).getType().equals(TripMapPointType.longlineActivityWithHaulingStart)) {

                Coordinate[] coordinates = {
                        new Coordinate(tripMapPoints.get(indexPoint - 1).getLongitude(), tripMapPoints.get(indexPoint - 1).getLatitude()),
                        new Coordinate(tripMapPoints.get(indexPoint).getLongitude(), tripMapPoints.get(indexPoint).getLatitude()),
                };

                boolean setting = tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithSettingEnd);
                LineString lineString = geometryFactory.createLineString(coordinates);
                lineBuilder.add(lineString);
                lineBuilder.add(setting ? "setting" : "hauling");
                SimpleFeature feature = lineBuilder.buildFeature(null);
                linesFeatures.add(feature);

                defaultLineCoordinates.clear();
            }

            if (!(tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithSettingEnd)
                    || tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithHaulingStart))) {

                defaultLineCoordinates.add(new Coordinate(tripMapPoints.get(indexPoint).getLongitude(), tripMapPoints.get(indexPoint).getLatitude()));

            }

            if ((tripMapPoints.get(indexPoint).getType().equals(TripMapPointType.longlineActivityWithSettingStart)
                    || indexPoint == tripMapPoints.size() - 1) && defaultLineCoordinates.size() > 1) {

                LineString lineString = geometryFactory.createLineString(defaultLineCoordinates.toArray(new Coordinate[0]));
                lineBuilder.add(lineString);
                lineBuilder.add("trip");
                SimpleFeature feature = lineBuilder.buildFeature(null);
                linesFeatures.add(feature);

                defaultLineCoordinates.clear();

            }


        }

        Style styleLines = findStyle(styledLayerDescriptor, TRIP_LONGLINE_LINE_LAYER_NAME, null);
        if (!linesFeatures.isEmpty()) {
            Layer layerLines = new FeatureLayer(linesFeatures, styleLines, TRIP_LONGLINE_LINE_LAYER_NAME);
            mapContent.addLayer(layerLines);
        }

        // add line in legend
        LineString line = geometryFactory.createLineString(ObserveMapPaneLegendItem.lineCoordinates());
        lineBuilder.add(line);
        lineBuilder.add("setting");

        ObserveMapPaneLegendItem legendTripDay = new ObserveMapPaneLegendItem(
                lineBuilder.buildFeature(null),
                styleLines,
                t("observe.content.map.legend.setting"));
        legendItems.add(legendTripDay);

        line = geometryFactory.createLineString(ObserveMapPaneLegendItem.lineCoordinates());
        lineBuilder.add(line);
        lineBuilder.add("hauling");

        legendTripDay = new ObserveMapPaneLegendItem(
                lineBuilder.buildFeature(null),
                styleLines,
                t("observe.content.map.legend.hauling"));
        legendItems.add(legendTripDay);


    }


    public void addPoints(List tripMapPoints) throws FactoryException {

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

        SimpleFeatureTypeBuilder pointFeatureTypeBuilder = new SimpleFeatureTypeBuilder();
        pointFeatureTypeBuilder.setName("point Builder");
        pointFeatureTypeBuilder.setCRS(CRS.decode("EPSG:4326", true));
        pointFeatureTypeBuilder.add("point", Point.class);
        pointFeatureTypeBuilder.add("label", String.class);
        pointFeatureTypeBuilder.add("pointType", String.class);

        SimpleFeatureType pointFeatureType = pointFeatureTypeBuilder.buildFeatureType();
        SimpleFeatureBuilder pointBuilder = new SimpleFeatureBuilder(pointFeatureType);

        DefaultFeatureCollection pointsFeatures = new DefaultFeatureCollection();

        Style stylePoints = findStyle(styledLayerDescriptor, TRIP_POINTS_LAYER_NAME, null);

        Set pointTypeInLegend = Sets.newHashSet();

        for (TripMapPoint tripMapPoint : tripMapPoints) {
            Coordinate coordinate = new Coordinate(tripMapPoint.getLongitude(), tripMapPoint.getLatitude());

            TripMapPointType type = tripMapPoint.getType();

            Point point = geometryFactory.createPoint(coordinate);
            pointBuilder.add(point);
            pointBuilder.add(DATE_FORMAT.format(tripMapPoint.getTime()));
            pointBuilder.add(type.name());
            pointsFeatures.add(pointBuilder.buildFeature(null));

            // add point in legend
            if (TRIP_MAP_POINT_TYPES_IN_LEGEND.contains(type) && !pointTypeInLegend.contains(type)) {
                point = geometryFactory.createPoint(ObserveMapPaneLegendItem.pointCoordinates());
                pointBuilder.add(point);
                pointBuilder.add("");
                pointBuilder.add(type.name());

                ObserveMapPaneLegendItem legendPoint = new ObserveMapPaneLegendItem(
                        pointBuilder.buildFeature(null),
                        stylePoints,
                        ObserveI18nDecoratorHelper.getLabel(type));
                legendItems.add(legendPoint);
                pointTypeInLegend.add(type);
            }

        }

        if (!pointsFeatures.isEmpty()) {
            Layer pointsLayer = new FeatureLayer(pointsFeatures, stylePoints, TRIP_POINTS_LAYER_NAME);
            mapContent.addLayer(pointsLayer);
        }

    }


    protected Style findStyle(StyledLayerDescriptor styledLayerDescriptor, final String layerName, String styleName, Style defaultStyle) {

        Optional styledLayerOptional = styledLayerDescriptor.layers().stream().filter(input -> input.getName().equals(layerName)).findFirst();

        Style style = defaultStyle;

        if (styledLayerOptional.isPresent()) {

            StyledLayer styledLayer = styledLayerOptional.get();

            Style[] styles = new Style[0];

            if (styledLayer instanceof UserLayer) {

                styles = ((UserLayer) styledLayer).getUserStyles();

            } else if (styledLayer instanceof NamedLayer) {

                styles = ((NamedLayer) styledLayer).getStyles();

            }

            if (styles.length == 1) {

                style = styles[0];

            } else {

                for (Style styleTmp : styles) {

                    if (StringUtils.isBlank(styleName) && styleTmp.isDefault()
                            || styleTmp.getName().equals(styleName)) {

                        style = styleTmp;
                    }
                }
            }
        }

        return style;

    }

    protected Style findStyle(StyledLayerDescriptor styledLayerDescriptor, final String layerName, String styleName) {

        Style style = findStyle(styledLayerDescriptor, layerName, styleName, null);

        if (style == null) {
            throw new ObserveClientTechnicalException(String.format("No style found for layer name '%s' and style name '%s'", layerName, styleName));
        }
        return style;

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy