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

src.gov.nasa.worldwind.formats.shapefile.ShapefileRecordPolygon Maven / Gradle / Ivy

Go to download

World Wind is a collection of components that interactively display 3D geographic information within Java applications or applets.

There is a newer version: 2.0.0-986
Show newest version
/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */
package gov.nasa.worldwind.formats.shapefile;

import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.ogc.kml.impl.KMLExportUtil;
import gov.nasa.worldwind.util.*;

import javax.xml.stream.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;

/**
 * Represents a Shapefile record with a polygon shape type. Polygon shapes represent an connected sequence of four or
 * more x,y coordinate pairs that form a closed loop. Polygon shapes may contain multiple rings, where each ring is a
 * closed loop of four or more points. Rings defining a filled part of a polygon have a clockwise winding order, while
 * rings defining holes in the polygon have a counter-clockwise winding order.
 * 

* Polygons may have optional z-coordinates or m-coordinates that accompany each coordinate pair. If a Polygon has * z-coordinates, then {@link #getZValues()} returns a non-null array of values. If a Polygon * has m-coordinates, then {@link #getMValues()} returns a non-null array of values. * * @author Patrick Murris * @version $Id: ShapefileRecordPolygon.java 1171 2013-02-11 21:45:02Z dcollins $ */ public class ShapefileRecordPolygon extends ShapefileRecordPolyline { /** {@inheritDoc} */ public ShapefileRecordPolygon(Shapefile shapeFile, ByteBuffer buffer) { super(shapeFile, buffer); } /** * Export the record to KML as a {@code } element. If the polygon has a "height" attribute it will be * exported as an extruded polygon. * * @param xmlWriter XML writer to receive the generated KML. * * @throws javax.xml.stream.XMLStreamException * If an exception occurs while writing the KML * @throws java.io.IOException If an exception occurs while exporting the data. */ @Override public void exportAsKML(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException { Iterable outerBoundary = null; List> innerBoundaries = new ArrayList>(); // If the polygon has a "height" attribute, export as an extruded polygon. Double height = ShapefileUtils.extractHeightAttribute(this); for (int i = 0; i < this.getNumberOfParts(); i++) { // Although the shapefile spec says that inner and outer boundaries can be listed in any order, it's // assumed here that inner boundaries are at least listed adjacent to their outer boundary, either // before or after it. The below code accumulates inner boundaries into the polygon until an // outer boundary comes along. If the outer boundary comes before the inner boundaries, the inner // boundaries are added to the polygon until another outer boundary comes along, at which point a new // polygon is started. VecBuffer buffer = this.getCompoundPointBuffer().subBuffer(i); if (WWMath.computeWindingOrderOfLocations(buffer.getLocations()).equals(AVKey.CLOCKWISE)) { if (outerBoundary == null) { outerBoundary = buffer.getLocations(); } else { this.exportPolygonAsKML(xmlWriter, outerBoundary, innerBoundaries, height); outerBoundary = this.getCompoundPointBuffer().getLocations(); innerBoundaries.clear(); } } else { innerBoundaries.add(buffer.getLocations()); } } if (outerBoundary != null && outerBoundary.iterator().hasNext()) { this.exportPolygonAsKML(xmlWriter, outerBoundary, innerBoundaries, height); } } protected void exportPolygonAsKML(XMLStreamWriter xmlWriter, Iterable outerBoundary, List> innerBoundaries, Double height) throws IOException, XMLStreamException { xmlWriter.writeStartElement("Placemark"); xmlWriter.writeStartElement("name"); xmlWriter.writeCharacters(Integer.toString(this.getRecordNumber())); xmlWriter.writeEndElement(); xmlWriter.writeStartElement("Polygon"); String altitudeMode; if (height != null) { xmlWriter.writeStartElement("extrude"); xmlWriter.writeCharacters("1"); xmlWriter.writeEndElement(); altitudeMode = "absolute"; } else { altitudeMode = "clampToGround"; height = 0.0; } xmlWriter.writeStartElement("altitudeMode"); xmlWriter.writeCharacters(altitudeMode); xmlWriter.writeEndElement(); xmlWriter.writeStartElement("outerBoundaryIs"); KMLExportUtil.exportBoundaryAsLinearRing(xmlWriter, outerBoundary, height); xmlWriter.writeEndElement(); // outerBoundaryIs for (Iterable innerBoundary : innerBoundaries) { xmlWriter.writeStartElement("innerBoundaryIs"); KMLExportUtil.exportBoundaryAsLinearRing(xmlWriter, innerBoundary, height); xmlWriter.writeEndElement(); // innerBoundaryIs } xmlWriter.writeEndElement(); // Polygon xmlWriter.writeEndElement(); // Placemark xmlWriter.flush(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy