Package org.osm2world.core.world.network

Source Code of org.osm2world.core.world.network.VisibleConnectorNodeWorldObject

package org.osm2world.core.world.network;

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

import org.osm2world.core.map_data.data.MapNode;
import org.osm2world.core.map_data.data.MapSegment;
import org.osm2world.core.map_data.data.MapWaySegment;
import org.osm2world.core.math.InvalidGeometryException;
import org.osm2world.core.math.SimplePolygonXZ;
import org.osm2world.core.math.VectorXZ;
import org.osm2world.core.world.creation.NetworkCalculator;
import org.osm2world.core.world.data.OutlineNodeWorldObject;

public abstract class VisibleConnectorNodeWorldObject
  extends OutlineNodeWorldObject {

  protected boolean informationProvided;
 
  protected VectorXZ cutVector;
  protected VectorXZ startPos;
  protected VectorXZ endPos;
  protected float startWidth;
  protected float endWidth;
 
  /**
   * returns the length required by this node representation.
   * Adjacent lines will be pushed back accordingly.
   *
   * If this is 0, this has the same effect as an invisible
   * connector node (adjacent line representations
   * directly touching each other). Examples where non-zero values
   * are needed include crossings at nodes in roads.
   *
   * Needs to be provided by the implementing class before the
   * calculation in {@link NetworkCalculator} starts.
   */
  abstract public float getLength();
 
  /**
   * sets the results of {@link NetworkCalculator}'s calculations.
   * Most methods in this class cannot be used until this method
   * has provided the required information!
   */
  public void setInformation(VectorXZ cutVector,
      VectorXZ startPos, VectorXZ endPos,
      float startWidth, float endWidth) {
   
    this.informationProvided = true;
   
    this.cutVector = cutVector;
    this.startPos = startPos;
    this.endPos = endPos;
    this.startWidth = startWidth;
    this.endWidth = endWidth;
   
  }
 
  public VisibleConnectorNodeWorldObject(MapNode node) {
    super(node);
  }
 
  @Override
  public SimplePolygonXZ getOutlinePolygonXZ() {
   
    List<VectorXZ> outlineXZ = new ArrayList<VectorXZ>(getOutlineXZ(0, 0));
    outlineXZ.addAll(getOutlineXZ(1, 1));
   
    if (outlineXZ.size() > 2) {
   
      try { //TODO better handling of broken outlines
        outlineXZ.add(outlineXZ.get(0));
        return new SimplePolygonXZ(outlineXZ);
      } catch (InvalidGeometryException e) {}
     
      }
   
    return null;
   
  }
 
  /**
   * provides outline for the areas covered by the connector.
   *
   * The from and to indices refer to the list
   * returned by the underlying {@link MapNode}'s
   * {@link MapNode#getConnectedSegments()} method.
   */
  protected List<VectorXZ> getOutlineXZ(int from, int to) {
 
    checkInformationProvided();
   
    List<VectorXZ> outline = new ArrayList<VectorXZ>();
 
    List<MapSegment> segments = node.getConnectedSegments();
 
    assert from >= 0 && from < segments.size();
    assert to >= 0 && to < segments.size();
 
    if (((from == 1 && to == 0) || (from == 0 && to == 1))) {
           
      if (from == 0) {
       
        VectorXZ pos1 = startPos
          .add(cutVector.mult(startWidth));
 
        VectorXZ pos2 = endPos
          .add(cutVector.mult(endWidth));
       
        outline.add(pos1);
        outline.add(pos2);
       
      } else {
 
        VectorXZ pos1 = endPos
          .subtract(cutVector.mult(endWidth));
 
        VectorXZ pos2 = startPos
          .subtract(cutVector.mult(startWidth));
       
        outline.add(pos1);
        outline.add(pos2);
       
      }
     
    } else if (from == to
        && segments.get(from) instanceof MapWaySegment) { //usually at the end of a noexit road
     
      MapWaySegment segment = (MapWaySegment) segments.get(from);
     
      if (segment.getPrimaryRepresentation() instanceof NetworkWaySegmentWorldObject) {
       
        NetworkWaySegmentWorldObject rep =
          (NetworkWaySegmentWorldObject) segment.getPrimaryRepresentation();
       
        //TODO: the calculations for pos1/2 should be part of the NetworkLineRepresentation (it's used quite often)
       
        if (segment.getEndNode() == node) { //inbound segment
         
          VectorXZ pos1 = node.getPos()
            .add(rep.getEndOffset())
            .add(rep.getEndCutVector().mult(rep.getWidth()/2));
         
          VectorXZ pos2 = node.getPos()
            .add(rep.getEndOffset())
            .subtract(rep.getEndCutVector().mult(rep.getWidth()/2));
                   
          outline.add(pos1);
          outline.add(pos2);
         
        } else { //outbound segment
 
          VectorXZ pos1 = node.getPos()
            .add(rep.getStartOffset())
            .subtract(rep.getStartCutVector().mult(rep.getWidth()/2));
         
          VectorXZ pos2 = node.getPos()
            .add(rep.getStartOffset())
            .add(rep.getStartCutVector().mult(rep.getWidth()/2));
 
          outline.add(pos1);
          outline.add(pos2);
                   
        }
       
      }
     
    }
   
    return outline;
   
  }
 
  /**
   * throws an IllegalStateException if information hasn't been
   * provided by a {@link NetworkCalculator}
   */
  private void checkInformationProvided() throws IllegalStateException {
    if (!informationProvided) {
      throw new IllegalStateException("no connector information"
          + " has been set for this representation.\n"
          + "node: " + node);
    }
  }
 
}
TOP

Related Classes of org.osm2world.core.world.network.VisibleConnectorNodeWorldObject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.