openlr.encoder.data.LocRefPoint.java Source code

Java tutorial

Introduction

Here is the source code for openlr.encoder.data.LocRefPoint.java

Source

/**
 * Licensed to the TomTom International B.V. under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  TomTom International B.V.
 * licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/**
 *  Copyright (C) 2009-2012 TomTom International B.V.
 *
 *   TomTom (Legal Department)
 *   Email: legal@tomtom.com
 *
 *   TomTom (Technical contact)
 *   Email: openlr@tomtom.com
 *
 *   Address: TomTom International B.V., Oosterdoksstraat 114, 1011DK Amsterdam,
 *   the Netherlands
 */
package openlr.encoder.data;

import java.util.ArrayList;
import java.util.List;

import openlr.LocationReferencePoint;
import openlr.OpenLRProcessingException;
import openlr.encoder.properties.OpenLREncoderProperties;
import openlr.map.FormOfWay;
import openlr.map.FunctionalRoadClass;
import openlr.map.GeoCoordinates;
import openlr.map.Line;
import openlr.map.Node;
import openlr.map.utils.GeometryUtils;
import openlr.map.utils.PathUtils;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * The Class LocRefPoint encapsulates the data for a location reference point.
 * This includes the line being represented by this LRP and the shortest-path to
 * the next location reference point. All relevant data for an LRP can be
 * calculated.
 * 
 * <p>
 * OpenLR is a trade mark of TomTom International B.V.
 * <p>
 * email: software@openlr.org
 * 
 * @author TomTom International B.V.
 */
public class LocRefPoint implements LocationReferencePoint {

    /** The LRP refers to this line. */
    private final Line line;

    /** The shortest-path to the next LRP. */
    private List<Line> subroute;

    /**
     * indicates whether the LRP is located directly on a line or refers to a
     * node
     */
    private final boolean isPointOnLine;

    /** indicates whether the LRP is the last one in the sequence or not */
    private boolean isLast;

    /** the longitude coordinate of the LRP */
    private final double longitude;

    /** the latitude coordinate of the LRP */
    private final double latitude;

    /** the next location reference point */
    private LocRefPoint next;

    /** the calculated bearing value */
    private double bearing;

    /** The sequence number. */
    private int sequenceNumber;

    /**
     * Instantiates a new location reference point based on a node. This LRP is
     * not the last LRP in the sequence of LRPs.
     * 
     * @param route
     *            the shortest-path to the next LRP
     * @param p
     *            the encoder properties
     * @throws OpenLRProcessingException
     *             the open lr processing exception
     */
    public LocRefPoint(final List<Line> route, final OpenLREncoderProperties p) throws OpenLRProcessingException {
        line = route.get(0);
        subroute = route;
        isPointOnLine = false;
        isLast = false;
        longitude = line.getStartNode().getLongitudeDeg();
        latitude = line.getStartNode().getLatitudeDeg();
        bearing = calculateBearing(p);
    }

    /**
     * Instantiates a new location reference point based on another LRP and
     * assigns a given route to it. Used to correct the route for the last
     * intermediate LRP of closed lines.
     * 
     * @param route
     *            the shortest-path to the next LRP
     * @param lrp
     *            the lrp to be copied (except for the route)
     * @throws OpenLRProcessingException
     *             the open lr processing exception
     */
    public LocRefPoint(final List<Line> route, final LocRefPoint lrp) throws OpenLRProcessingException {
        line = lrp.line;
        subroute = route;
        isPointOnLine = lrp.isLRPOnLine();
        isLast = lrp.isLastLRP();
        longitude = lrp.getLongitudeDeg();
        latitude = lrp.getLatitudeDeg();
        bearing = lrp.getBearing();
        next = lrp.next;
        sequenceNumber = lrp.getSequenceNumber();
    }

    /**
     * Instantiates a new loc ref point.
     * 
     * @param coord
     *            the coord
     */
    public LocRefPoint(final GeoCoordinates coord) {
        line = null;
        subroute = null;
        isPointOnLine = false;
        isLast = false;
        longitude = coord.getLongitudeDeg();
        latitude = coord.getLatitudeDeg();
        bearing = 0;
    }

    /**
     * Sets the next location reference point.
     * 
     * @param n
     *            the next location reference point
     */
    public final void setNextLRP(final LocRefPoint n) {
        next = n;
    }

    /**
     * Instantiates a new location reference point based on a node and this LRP
     * is the last LRP in the sequence of the LRPs.
     * 
     * @param l
     *            the referenced line
     * @param p
     *            the encoder properties
     * @throws OpenLRProcessingException
     *             the open lr processing exception
     */
    public LocRefPoint(final Line l, final OpenLREncoderProperties p) throws OpenLRProcessingException {
        line = l;
        subroute = null;
        isPointOnLine = false;
        isLast = true;
        longitude = l.getEndNode().getLongitudeDeg();
        latitude = l.getEndNode().getLatitudeDeg();
        bearing = calculateBearing(p);
    }

    /**
     * Instantiates a new location reference point based on a point directly on
     * a line. This LRP is not based on a node and it is not the last LRP in the
     * sequence of LRPs.
     *
     * @param l the line containing the referenced point
     * @param lon the longitude coordinate of the point
     * @param lat the latitude coordinate of the point
     * @param p the encoder properties
     * @param lastLRP the last lrp
     * @throws OpenLRProcessingException the open lr processing exception
     */
    public LocRefPoint(final Line l, final double lon, final double lat, final OpenLREncoderProperties p,
            final boolean lastLRP) throws OpenLRProcessingException {
        line = l;
        subroute = new ArrayList<Line>(1);
        subroute.add(l);
        isPointOnLine = true;
        isLast = lastLRP;
        longitude = lon;
        latitude = lat;
        bearing = calculateBearing(p);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final double getLongitudeDeg() {
        return longitude;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final double getLatitudeDeg() {
        return latitude;
    }

    /**
     * Gets the LRP node.
     * 
     * @return the LRP node
     */
    public final Node getLRPNode() {
        if (line == null) {
            throw new UnsupportedOperationException();
        }
        Node n = null;
        if (!isPointOnLine) {
            if (!isLast) {
                n = line.getStartNode();
            } else {
                n = line.getEndNode();
            }
        }
        return n;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int getDistanceToNext() {
        int dist = 0;
        // last LRP has distance 0 for all other LRP the distance will be
        // calculated
        if (!isLast) {
            if (isPointOnLine) {
                // if LRP is a point on a line there is no route available
                if (next != null && next.isPointOnLine) {
                    // next LRP is on the same line, so dist is the difference
                    dist = next.line.measureAlongLine(next.longitude, next.latitude)
                            - line.measureAlongLine(longitude, latitude);
                } else {
                    // next LRP is node based, so distance is rest of the line
                    dist = line.getLineLength() - line.measureAlongLine(longitude, latitude);
                }
            } else {
                // LRP is node based
                if (next != null && next.isPointOnLine) {
                    // next LRP is on that line, so distance from start is
                    // required
                    dist += next.line.measureAlongLine(next.longitude, next.latitude);
                } else {
                    // next LRP is node based, so take the route distance
                    dist = PathUtils.getLength(subroute);
                }
            }
        }
        return dist;
    }

    /**
     * Gets the shortest-path to the next LRP.
     * 
     * @return the shortest-path to the next LRP or null if it is the last LRP
     */
    public final List<Line> getRoute() {
        return subroute;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final FunctionalRoadClass getLfrc() {
        if (line == null) {
            throw new UnsupportedOperationException();
        }
        FunctionalRoadClass lfrc = null;
        if (isPointOnLine) {
            lfrc = line.getFRC();
        } else if (subroute != null && subroute.size() > 0) {
            // setup data
            int frcID = 0;
            // iterate over the whole route
            for (Line ds : subroute) {
                frcID = Math.max(frcID, ds.getFRC().getID());
            }
            return FunctionalRoadClass.getFRCs().get(frcID);
        }
        return lfrc;
    }

    /**
     * Gets the bearing of the referenced line.
     * 
     * @param properties
     *            the properties
     * @return the bearing of the referenced line
     * @throws OpenLRProcessingException
     *             the open lr processing exception
     */
    private double calculateBearing(final OpenLREncoderProperties properties) throws OpenLRProcessingException {
        GeometryUtils.BearingDirection dir = null;
        if (!isLast) {
            dir = GeometryUtils.BearingDirection.IN_DIRECTION;
        } else {
            dir = GeometryUtils.BearingDirection.AGAINST_DIRECTION;
        }
        int projection = 0;
        if (isPointOnLine) {
            projection = line.measureAlongLine(longitude, latitude);
        }
        double b = GeometryUtils.calculateLineBearing(line, dir, properties.getBearingDistance(), projection);
        return b;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final FormOfWay getFOW() {
        if (line == null) {
            throw new UnsupportedOperationException();
        }
        return line.getFOW();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final FunctionalRoadClass getFRC() {
        if (line == null) {
            throw new UnsupportedOperationException();
        }
        return line.getFRC();
    }

    /**
     * Checks if this LRP is based directly on a line. It returns false if the
     * LRP is based on a node.
     * 
     * @return true, if the LRP is based on a line
     */
    public final boolean isLRPOnLine() {
        return isPointOnLine;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean isLastLRP() {
        return isLast;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final double getBearing() {
        return bearing;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("line: ").append(line.getID());
        sb.append(" lon: ").append(longitude);
        sb.append(" lat: ").append(latitude);
        sb.append(" bear: ").append(bearing);
        sb.append(" isPointOnLine: ").append(isPointOnLine);
        sb.append(" isLast: ").append(isLast);
        if ((next != null) && (next.getRoute() != null) && !next.getRoute().isEmpty()) {
            sb.append(" next lrp line: ").append(next.getRoute().get(0).getID());
        }
        if (subroute != null && !subroute.isEmpty()) {
            sb.append(" [");
            for (int i = 0; i < subroute.size(); i++) {
                sb.append(subroute.get(i).getID());
                if (i != subroute.size() - 1) {
                    sb.append(",");
                }
            }
            sb.append("]");
        }
        return sb.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int hashCode() {
        HashCodeBuilder builder = new HashCodeBuilder();
        builder.append(bearing).append(subroute).append(line).append(next).append(isPointOnLine).append(isLast)
                .append(longitude).append(latitude);
        return builder.toHashCode();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean equals(final Object obj) {
        if (!(obj instanceof LocRefPoint)) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        LocRefPoint other = (LocRefPoint) obj;
        EqualsBuilder builder = new EqualsBuilder();
        builder.append(bearing, other.bearing).append(subroute, other.subroute).append(line, other.line)
                .append(next, other.next).append(isPointOnLine, other.isPointOnLine).append(isLast, other.isLast)
                .append(longitude, other.longitude).append(latitude, other.latitude);
        return builder.isEquals();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int getSequenceNumber() {
        return sequenceNumber;
    }

    /**
     * Sets the sequence number.
     * 
     * @param seqNr
     *            the new sequence number
     */
    public final void setSequenceNumber(final int seqNr) {
        sequenceNumber = seqNr;
    }

    /**
     * Gets the referenced line.
     *
     * @return the referenced line
     */
    public final Line getLine() {
        return line;
    }

    /**
     * Gets the last line of sub route or null if no sub route exists.
     *
     * @return the last line of sub route
     */
    public final Line getLastLineOfSubRoute() {
        if (subroute != null) {
            return subroute.get(subroute.size() - 1);
        }
        return null;
    }

}