Package org.osm2world.core.map_data.data

Source Code of org.osm2world.core.map_data.data.MapArea

package org.osm2world.core.map_data.data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.openstreetmap.josm.plugins.graphview.core.data.TagGroup;
import org.osm2world.core.map_data.data.overlaps.MapOverlap;
import org.osm2world.core.math.AxisAlignedBoundingBoxXZ;
import org.osm2world.core.math.InvalidGeometryException;
import org.osm2world.core.math.PolygonWithHolesXZ;
import org.osm2world.core.math.SimplePolygonXZ;
import org.osm2world.core.math.VectorXZ;
import org.osm2world.core.osm.data.OSMElement;
import org.osm2world.core.world.data.AreaWorldObject;

public class MapArea implements MapElement {

  private final OSMElement objectWithTags;
 
  private final List<MapNode> nodes;
  private final List<List<MapNode>> holes;
 
  private final PolygonWithHolesXZ polygon;
   
  private Collection<MapAreaSegment> areaSegments;

  @SuppressWarnings("unchecked") //is later checked for EMPTY_LIST using ==
  private Collection<MapOverlap<?,?>> overlaps = Collections.EMPTY_LIST;
 
  private List<AreaWorldObject> representations =
    new ArrayList<AreaWorldObject>(1);
 
  //TODO: contained / intersecting nodes/lines
 
  public MapArea(OSMElement objectWithTags, List<MapNode> nodes) {
    this(objectWithTags, nodes, Collections.<List<MapNode>>emptyList());
  }
 
  public MapArea(OSMElement objectWithTags, List<MapNode> nodes,
      List<List<MapNode>> holes) {
   
    this.objectWithTags = objectWithTags;
    this.nodes = nodes;
    this.holes = holes;
   
    try {
     
      this.polygon = convertToPolygon(nodes, holes);
     
    } catch (InvalidGeometryException e) {
      throw new InvalidGeometryException(
          "outer polygon is not simple for this object: "
          + objectWithTags, e);
    }
   
  }
 
  public MapArea(OSMElement objectWithTags, List<MapNode> nodes,
      List<List<MapNode>> holes, PolygonWithHolesXZ polygon) {
   
    this.objectWithTags = objectWithTags;
    this.nodes = nodes;
    this.holes = holes;
    this.polygon = polygon;
   
  }
 
  private static final PolygonWithHolesXZ convertToPolygon(
      List<MapNode> nodes, List<List<MapNode>> holes) {
   
    SimplePolygonXZ outerPolygon =
        polygonFromMapNodeLoop(nodes);
   
    List<SimplePolygonXZ> holePolygons =
      new ArrayList<SimplePolygonXZ>(holes.size());
    for (List<MapNode> hole : holes) {
      holePolygons.add(polygonFromMapNodeLoop(hole));
    }
   
    return new PolygonWithHolesXZ(outerPolygon, holePolygons);
       
  }

  public static final SimplePolygonXZ polygonFromMapNodeLoop(
      List<MapNode> nodes) {
   
    List<VectorXZ> vertices = new ArrayList<VectorXZ>(nodes.size());
   
    for (MapNode node : nodes) {
      vertices.add(node.getPos());
    }
   
    return new SimplePolygonXZ(vertices);
   
  }

  public List<MapNode> getBoundaryNodes() {
    return nodes;
  }
 
  @Override
  public int getLayer() {
    if (objectWithTags.tags.containsKey("layer")) {
      try {
        return Integer.parseInt(objectWithTags.tags.getValue("layer"));
      } catch (NumberFormatException nfe) {
        return 0;
      }
    }
    return 0;
  }
 
  public Collection<List<MapNode>> getHoles() {
    return holes;
  }
 
  /** returns the way or relation with the tags for this area */
  public OSMElement getOsmObject() {
    return objectWithTags;
  }

  @Override
  public TagGroup getTags() {
    return objectWithTags.tags;
  }
 
  /**
   * returns the area as a polygon.
   */
  public PolygonWithHolesXZ getPolygon() {
    return polygon;
  }

  public SimplePolygonXZ getOuterPolygon() {
    return getPolygon().getOuter();
  }
 
  /**
   * returns the segments making up this area's outer and inner boundaries
   */
  public Collection<MapAreaSegment> getAreaSegments() {
   
    if (areaSegments == null) {
   
      areaSegments = new ArrayList<MapAreaSegment>();
     
      for (int v = 0; v+1 < nodes.size(); v++) {
        //relies on duplication of first/last node
       
        areaSegments.add(new MapAreaSegment(this,
            getPolygon().getOuter().isClockwise(),
            nodes.get(v), nodes.get(v+1)));
               
      }
     
      for (int h = 0; h < holes.size(); h++) {
       
        List<MapNode> holeNodes = holes.get(h);
        SimplePolygonXZ holePolygon = polygon.getHoles().get(h);
       
        for (int v = 0; v+1 < holeNodes.size(); v++) {
          //relies on duplication of first/last node
         
          areaSegments.add(new MapAreaSegment(this,
              !holePolygon.isClockwise(),
              holeNodes.get(v), holeNodes.get(v+1)));
         
        }
       
      }
     
    }
   
    return areaSegments;
   
  }
 
  @Override
  public List<AreaWorldObject> getRepresentations() {
    return representations;
  }
 
  @Override
  public AreaWorldObject getPrimaryRepresentation() {
    if (representations.isEmpty()) {
      return null;
    } else {
      return representations.get(0);
    }
  }

  /**
   * adds a visual representation for this area
   */
  public void addRepresentation(AreaWorldObject representation) {
    this.representations.add(representation);
  }
 
  public void addOverlap(MapOverlap<?, ?> overlap) {
    assert overlap.e1 == this || overlap.e2 == this;
    if (overlaps == Collections.EMPTY_LIST) {
      overlaps = new ArrayList<MapOverlap<?,?>>();
    }
    overlaps.add(overlap);
  }

  @Override
  public Collection<MapOverlap<?,?>> getOverlaps() {
    return overlaps;
  }

  @Override
  public AxisAlignedBoundingBoxXZ getAxisAlignedBoundingBoxXZ() {
    return new AxisAlignedBoundingBoxXZ(getOuterPolygon().getVertexCollection());
  }
 
  @Override
  public String toString() {
    return objectWithTags.toString();
  }
 
}
TOP

Related Classes of org.osm2world.core.map_data.data.MapArea

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.