fr.certu.chouette.validation.checkpoint.AbstractValidation.java Source code

Java tutorial

Introduction

Here is the source code for fr.certu.chouette.validation.checkpoint.AbstractValidation.java

Source

/**
 * Projet CHOUETTE
 *
 * ce projet est sous license libre
 * voir LICENSE.txt pour plus de details
 *
 */

package fr.certu.chouette.validation.checkpoint;

import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import lombok.extern.log4j.Log4j;

import org.json.JSONArray;
import org.json.JSONObject;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.PrecisionModel;

import fr.certu.chouette.model.neptune.NeptuneIdentifiedObject;
import fr.certu.chouette.model.neptune.NeptuneLocalizedObject;
import fr.certu.chouette.model.neptune.type.LongLatTypeEnum;
import fr.certu.chouette.plugin.report.Report;
import fr.certu.chouette.plugin.validation.report.CheckPointReportItem;
import fr.certu.chouette.plugin.validation.report.DetailReportItem;
import fr.certu.chouette.plugin.validation.report.PhaseReportItem;
import fr.certu.chouette.plugin.validation.report.ReportLocation;

/**
 * @author michel
 * 
 */
@Log4j
public abstract class AbstractValidation {
    // test keys
    protected static final String STOP_AREA_1 = "3-StopArea-1";
    protected static final String STOP_AREA_2 = "3-StopArea-2";
    protected static final String STOP_AREA_3 = "3-StopArea-3";
    protected static final String STOP_AREA_4 = "3-StopArea-4";
    protected static final String STOP_AREA_5 = "3-StopArea-5";
    protected static final String STOP_AREA_6 = "3-StopArea-6";
    protected static final String ACCESS_POINT_1 = "3-AccessPoint-1";
    protected static final String ACCESS_POINT_2 = "3-AccessPoint-2";
    protected static final String ACCESS_POINT_3 = "3-AccessPoint-3";
    protected static final String CONNECTION_LINK_1 = "3-ConnectionLink-1";
    protected static final String CONNECTION_LINK_2 = "3-ConnectionLink-2";
    protected static final String CONNECTION_LINK_3 = "3-ConnectionLink-3";
    protected static final String ACCESS_LINK_1 = "3-AccessLink-1";
    protected static final String ACCESS_LINK_2 = "3-AccessLink-2";
    protected static final String ACCESS_LINK_3 = "3-AccessLink-3";
    protected static final String LINE_1 = "3-Line-1";
    protected static final String LINE_2 = "3-Line-2";
    protected static final String LINE_3 = "3-Line-3";
    protected static final String ROUTE_1 = "3-Route-1";
    protected static final String ROUTE_2 = "3-Route-2";
    protected static final String ROUTE_3 = "3-Route-3";
    protected static final String ROUTE_4 = "3-Route-4";
    protected static final String ROUTE_5 = "3-Route-5";
    protected static final String ROUTE_6 = "3-Route-6";
    protected static final String ROUTE_7 = "3-Route-7";
    protected static final String ROUTE_8 = "3-Route-8";
    protected static final String ROUTE_9 = "3-Route-9";
    protected static final String JOURNEY_PATTERN_1 = "3-JourneyPattern-1";
    protected static final String VEHICLE_JOURNEY_1 = "3-VehicleJourney-1";
    protected static final String VEHICLE_JOURNEY_2 = "3-VehicleJourney-2";
    protected static final String VEHICLE_JOURNEY_3 = "3-VehicleJourney-3";
    protected static final String VEHICLE_JOURNEY_4 = "3-VehicleJourney-4";
    protected static final String VEHICLE_JOURNEY_5 = "3-VehicleJourney-5";
    protected static final String VEHICLE_JOURNEY_6 = "3-VehicleJourney-6";
    protected static final String FACILITY_1 = "3-Facility-1";
    protected static final String FACILITY_2 = "3-Facility-2";

    // parameter keys
    protected static final String STOP_AREAS_AREA = "stop_areas_area";
    protected static final String INTER_STOP_AREA_DISTANCE_MIN = "inter_stop_area_distance_min";
    protected static final String PARENT_STOP_AREA_DISTANCE_MAX = "parent_stop_area_distance_max";
    protected static final String INTER_ACCESS_POINT_DISTANCE_MIN = "inter_access_point_distance_min";
    protected static final String INTER_CONNECTION_LINK_DISTANCE_MAX = "inter_connection_link_distance_max";
    protected static final String WALK_DEFAULT_SPEED_MAX = "walk_default_speed_max";
    protected static final String WALK_OCCASIONAL_TRAVELLER_SPEED_MAX = "walk_occasional_traveller_speed_max";
    protected static final String WALK_FREQUENT_TRAVELLER_SPEED_MAX = "walk_frequent_traveller_speed_max";
    protected static final String WALK_MOBILITY_RESTRICTED_TRAVELLER_SPEED_MAX = "walk_mobility_restricted_traveller_speed_max";
    protected static final String INTER_ACCESS_LINK_DISTANCE_MAX = "inter_access_link_distance_max";
    protected static final String INTER_STOP_DURATION_MAX = "inter_stop_duration_max";
    protected static final String FACILITY_STOP_AREA_DISTANCE_MAX = "facility_stop_area_distance_max";
    protected static final String MODE_PREFIX = "mode_";
    protected static final String MODE_OTHER = "mode_other";
    protected static final String INTER_STOP_AREA_DISTANCE_MAX = "inter_stop_area_distance_max";
    protected static final String SPEED_MAX = "speed_max";
    protected static final String SPEED_MIN = "speed_min";
    protected static final String INTER_STOP_DURATION_VARIATION_MAX = "inter_stop_duration_variation_max";
    protected static final String CHECK_ALLOWED_TRANSPORT_MODES = "check_allowed_transport_modes";
    protected static final String ALLOWED_TRANSPORT = "allowed_transport";
    protected static final String VEHICLE_JOURNEY_NUMBER_MIN = "vehicle_journey_number_min";
    protected static final String VEHICLE_JOURNEY_NUMBER_MAX = "vehicle_journey_number_max";

    protected static final JSONObject mode_default = new JSONObject(" {" + "\"allowed_transport\": 1, "
            + "\"inter_stop_area_distance_min\": 300, " + "\"inter_stop_area_distance_max\": 30000, "
            + "\"speed_max\": 40, " + "\"speed_min\": 10, " + "\"inter_stop_duration_variation_max\": 10 " + "}");

    private GeometryFactory geometryFactory;

    /**
     * create checkPoint entry with status uncheck
     * 
     * @param validationItem
     * @param checkPointKey
     * @param severity
     */
    protected void initCheckPoint(PhaseReportItem validationItem, String checkPointKey,
            CheckPointReportItem.SEVERITY severity) {
        int order = validationItem.hasItems() ? validationItem.getItems().size() : 0;
        validationItem.addItem(new CheckPointReportItem(checkPointKey, order, Report.STATE.UNCHECK, severity));
    }

    /**
     * pass checkpoint to ok if uncheck
     * 
     * @param validationReport
     * @param checkPointKey
     */
    protected void prepareCheckPoint(PhaseReportItem validationReport, String checkPointKey) {
        CheckPointReportItem checkPoint = validationReport.getItem(checkPointKey);
        if (!checkPoint.hasItems())
            checkPoint.updateStatus(Report.STATE.OK);
    }

    /**
     * add a detail on a checkpoint
     * 
     * @param validationReport
     * @param checkPointKey
     * @param item
     */
    protected void addValidationError(PhaseReportItem validationReport, String checkPointKey,
            DetailReportItem item) {
        CheckPointReportItem checkPoint = validationReport.getItem(checkPointKey);
        checkPoint.addItem(item);

    }

    /**
     * check if an object has coordinates
     * 
     * @param obj
     * @return
     */
    protected boolean hasCoordinates(NeptuneLocalizedObject obj) {
        return obj.getLongLatType() != null && obj.getLongitude() != null && obj.getLatitude() != null;
    }

    /**
     * calculate distance on spheroid
     * 
     * return 0 if one object has no coordinate
     * 
     * @param obj1
     * @param obj2
     * @return
     */
    protected double distance(NeptuneLocalizedObject obj1, NeptuneLocalizedObject obj2) {
        if (obj1.hasCoordinates() && obj2.hasCoordinates())
            return computeHaversineFormula(obj1, obj2);
        else
            return 0;
    }

    /**
     * @see http://mathforum.org/library/drmath/view/51879.html
     */
    private double computeHaversineFormula(NeptuneLocalizedObject obj1, NeptuneLocalizedObject obj2) {

        double lon1 = Math.toRadians(obj1.getLongitude().doubleValue());
        double lat1 = Math.toRadians(obj1.getLatitude().doubleValue());
        double lon2 = Math.toRadians(obj2.getLongitude().doubleValue());
        double lat2 = Math.toRadians(obj2.getLatitude().doubleValue());

        final double R = 6371008.8;

        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;

        double a = Math.pow((Math.sin(dlat / 2)), 2)
                + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon / 2), 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = R * c;

        return d;
    }

    protected boolean isEmpty(List<? extends Object> list) {
        return list == null || list.isEmpty();
    }

    protected boolean isEmpty(String string) {
        return string == null || string.isEmpty();
    }

    protected String toUnderscore(String camelcase) {

        return camelcase.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
    }

    protected long getModeParameter(JSONObject parameters, String modeKey, String key) {
        // find transportMode :
        modeKey = MODE_PREFIX + toUnderscore(modeKey);
        JSONObject mode = parameters.optJSONObject(modeKey);
        JSONObject modeOther = parameters.optJSONObject(MODE_OTHER);
        if (mode == null || !mode.has(key)) {
            log.error("no parameter " + key + " for mode " + modeKey);
            mode = parameters.optJSONObject(MODE_OTHER);
            if (modeOther == null || !modeOther.has(key)) {
                log.error("no parameter " + key + " for mode " + MODE_OTHER);
                mode = mode_default;
            }
        }
        return mode.getLong(key);
    }

    /**
     * @param parameters
     * @return
     */
    protected Polygon getEnveloppe(JSONObject parameters) {
        // validationPerimeter : defalut = France
        String perimeter = parameters.optString(STOP_AREAS_AREA,
                "[[-5.2,42.25],[-5.2,51.1],[8.23,51.1],[8.23,42.25],[-5.2,42.25]]");
        JSONArray array = new JSONArray(perimeter);
        List<Coordinate> listCoordinates = new ArrayList<Coordinate>();
        for (int i = 0; i < array.length(); i++) {
            JSONArray coords = array.getJSONArray(i);
            Coordinate coord = new Coordinate(coords.getDouble(0), coords.getDouble(1));
            listCoordinates.add(coord);
        }
        if (!listCoordinates.get(0).equals(listCoordinates.get(listCoordinates.size() - 1))) {
            listCoordinates.add(listCoordinates.get(0));
        }
        Coordinate[] coordinates = listCoordinates.toArray(new Coordinate[0]);
        LinearRing shell = getGeometryFactory().createLinearRing(coordinates);
        LinearRing[] holes = null;
        Polygon polygon = getGeometryFactory().createPolygon(shell, holes);
        return polygon;
    }

    private GeometryFactory getGeometryFactory() {
        if (geometryFactory == null) {
            PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.maximumPreciseValue);
            geometryFactory = new GeometryFactory(precisionModel, LongLatTypeEnum.WGS84.getValue());
        }
        return geometryFactory;
    }

    protected Point buildPoint(NeptuneLocalizedObject obj) {
        double y1 = obj.getLatitude().doubleValue();
        double x1 = obj.getLongitude().doubleValue();
        Coordinate coordinate = new Coordinate(x1, y1);
        Point point = getGeometryFactory().createPoint(coordinate);
        return point;
    }

    /**
     * @param report
     * @param object
     * @param duration
     * @param distance
     * @param maxDefaultSpeed
     * @param testCode
     * @param resultCode
     */
    protected void checkLinkSpeed(PhaseReportItem report, NeptuneIdentifiedObject object, Time duration,
            double distance, int maxDefaultSpeed, String testCode, String resultCode) {
        if (duration != null) {
            long time = getTimeInSeconds(duration); // in seconds

            if (time > 0) {
                int speed = (int) (distance / (double) time * 36 / 10 + 0.5); // (km/h)

                if (speed > maxDefaultSpeed) {
                    ReportLocation location = new ReportLocation(object);

                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("name", object.getName());
                    map.put("speed", Integer.valueOf(speed));
                    map.put("speedLimit", Integer.valueOf(maxDefaultSpeed));

                    DetailReportItem detail = new DetailReportItem(testCode + resultCode, object.getObjectId(),
                            Report.STATE.WARNING, location, map);
                    addValidationError(report, testCode, detail);
                }
            }
        }
    }

    protected long getTimeInSeconds(Time time) {
        TimeZone tz = TimeZone.getDefault();
        long millis = 0;
        millis = time.getTime() + tz.getRawOffset();
        return millis / 1000;
    }

}