/** {@inheritDoc} */ public Iterable<AVList> getLinks() { if (this.webViewWindowPtr != 0) { AVList[] links = WindowsWebViewJNI.getLinks(this.webViewWindowPtr); if (links != null) return Arrays.asList(links); } return Collections.emptyList(); }
protected Extent computeExtent(Globe globe, double verticalExaggeration) { List<Vec4> points = this.computeMinimalGeometry(globe, verticalExaggeration); if (points == null || points.isEmpty()) return null; // Add a point at the center of this polygon to the points used to compute its extent. The // center point captures // the curvature of the globe when the polygon's minimal geometry only contain any points near // the polygon's // edges. Vec4 centerPoint = Vec4.computeAveragePoint(points); LatLon centerLocation = globe.computePositionFromPoint(centerPoint); this.makeExtremePoints(globe, verticalExaggeration, Arrays.asList(centerLocation), points); return Box.computeBoundingBox(points); }
/** * Create a collection of layer lists and their included layers described by an array of XML * layer-list description elements. * * <p>Any exceptions occurring during creation of the layer lists or their included layers are * logged and not re-thrown. The layers associated with the exceptions are not included in the * returned layer list. * * @param elements the XML elements describing the layer lists to create. * @param params any parameters to apply when creating the included layers. * @return an array containing the specified layer lists. */ protected LayerList[] createLayerLists(Element[] elements, AVList params) { ArrayList<LayerList> layerLists = new ArrayList<LayerList>(); for (Element element : elements) { try { String href = WWXML.getText(element, "@href"); if (href != null && href.length() > 0) { Object o = this.createFromConfigSource(href, params); if (o == null) continue; if (o instanceof Layer) { LayerList ll = new LayerList(); ll.add((Layer) o); o = ll; } if (o instanceof LayerList) { LayerList list = (LayerList) o; if (list != null && list.size() > 0) layerLists.add(list); } else if (o instanceof LayerList[]) { LayerList[] lists = (LayerList[]) o; if (lists != null && lists.length > 0) layerLists.addAll(Arrays.asList(lists)); } else { String msg = Logging.getMessage("LayerFactory.UnexpectedTypeForLayer", o.getClass().getName()); Logging.logger().log(java.util.logging.Level.WARNING, msg); } continue; } String title = WWXML.getText(element, "@title"); Element[] children = WWXML.getElements(element, "./Layer", null); if (children != null && children.length > 0) { LayerList list = this.createLayerList(children, params); if (list != null && list.size() > 0) { layerLists.add(list); if (title != null && title.length() > 0) list.setValue(AVKey.DISPLAY_NAME, title); } } } catch (Exception e) { Logging.logger().log(java.util.logging.Level.WARNING, e.getMessage(), e); // keep going to create other layers } } return layerLists.toArray(new LayerList[layerLists.size()]); }
public List<Tile> getTiles() { if (tileKeys.isEmpty()) { Tile[] tiles = buildTiles(this.placeNameService, this); // load tileKeys for (Tile t : tiles) { tileKeys.add(t.getFileCachePath()); WorldWind.getMemoryCache(Tile.class.getName()).add(t.getFileCachePath(), t); } return Arrays.asList(tiles); } else { List<Tile> dataTiles = new ArrayList<Tile>(); for (String s : tileKeys) { Tile t = (Tile) WorldWind.getMemoryCache(Tile.class.getName()).getObject(s); if (t != null) { dataTiles.add(t); } } return dataTiles; } }
protected void doMoveTo(Position oldRef, Position newRef) { if (oldRef == null) { String message = "nullValue.OldRefIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (newRef == null) { String message = "nullValue.NewRefIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } super.doMoveTo(oldRef, newRef); int count = this.locations.size(); LatLon[] newLocations = new LatLon[count]; for (int i = 0; i < count; i++) { LatLon ll = this.locations.get(i); double distance = LatLon.greatCircleDistance(oldRef, ll).radians; double azimuth = LatLon.greatCircleAzimuth(oldRef, ll).radians; newLocations[i] = LatLon.greatCircleEndPosition(newRef, azimuth, distance); } this.setLocations(Arrays.asList(newLocations)); }
protected List<Sector> computeSectors(Globe globe) { if (this.sector == null || this.sector.equals(Sector.EMPTY_SECTOR)) return null; return Arrays.asList(this.sector); }
protected int computeCartesianPolygon( Globe globe, List<? extends LatLon> locations, List<Boolean> edgeFlags, Vec4[] points, Boolean[] edgeFlagArray, Matrix[] transform) { if (globe == null) { String message = Logging.getMessage("nullValue.GlobeIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (locations == null) { String message = "nullValue.LocationsIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (points == null) { String message = "nullValue.LocationsIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (points.length < (1 + locations.size())) { String message = Logging.getMessage( "generic.ArrayInvalidLength", "points.length < " + (1 + locations.size())); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (transform == null) { String message = "nullValue.TransformIsNull"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (transform.length < 1) { String message = Logging.getMessage("generic.ArrayInvalidLength", "transform.length < 1"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Allocate space to hold the list of locations and location vertices. int locationCount = locations.size(); // Compute the cartesian points for each location. for (int i = 0; i < locationCount; i++) { LatLon ll = locations.get(i); points[i] = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0.0); if (edgeFlagArray != null) edgeFlagArray[i] = (edgeFlags != null) ? edgeFlags.get(i) : true; } // Compute the average of the cartesian points. Vec4 centerPoint = Vec4.computeAveragePoint(Arrays.asList(points)); // Test whether the polygon is closed. If it is not closed, repeat the first vertex. if (!points[0].equals(points[locationCount - 1])) { points[locationCount] = points[0]; if (edgeFlagArray != null) edgeFlagArray[locationCount] = edgeFlagArray[0]; locationCount++; } // Compute a transform that will map the cartesian points to a local coordinate system centered // at the average // of the points and oriented with the globe surface. Position centerPos = globe.computePositionFromPoint(centerPoint); Matrix tx = globe.computeSurfaceOrientationAtPosition(centerPos); Matrix txInv = tx.getInverse(); // Map the cartesian points to a local coordinate space. for (int i = 0; i < locationCount; i++) { points[i] = points[i].transformBy4(txInv); } transform[0] = tx; return locationCount; }
/** * Represents a single record of a shapefile. * * @author Patrick Murris * @version $Id$ */ public abstract class ShapefileRecord { protected Shapefile shapeFile; protected int recordNumber; protected int contentLengthInBytes; protected String shapeType; protected DBaseRecord attributes; protected int numberOfParts; protected int numberOfPoints; protected int firstPartNumber; /** Indicates if the record's point coordinates should be normalized. Defaults to false. */ protected boolean normalizePoints; protected static final int RECORD_HEADER_LENGTH = 8; protected static List<String> measureTypes = new ArrayList<String>( Arrays.asList( Shapefile.SHAPE_POINT_M, Shapefile.SHAPE_POINT_Z, Shapefile.SHAPE_MULTI_POINT_M, Shapefile.SHAPE_MULTI_POINT_Z, Shapefile.SHAPE_POLYLINE_M, Shapefile.SHAPE_POLYLINE_Z, Shapefile.SHAPE_POLYGON_M, Shapefile.SHAPE_POLYGON_Z)); /** * Constructs a record instance from the given {@link java.nio.ByteBuffer}. The buffer's current * position must be the start of the record, and will be the start of the next record when the * constructor returns. * * @param shapeFile the parent {@link Shapefile}. * @param buffer the shapefile record {@link java.nio.ByteBuffer} to read from. * @throws IllegalArgumentException if any argument is null or otherwise invalid. * @throws gov.nasa.worldwind.exception.WWRuntimeException if the record's shape type does not * match that of the shapefile. */ public ShapefileRecord(Shapefile shapeFile, ByteBuffer buffer) { if (shapeFile == null) { String message = Logging.getMessage("nullValue.ShapefileIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (buffer == null) { String message = Logging.getMessage("nullValue.BufferIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Save the buffer's current position. int pos = buffer.position(); try { this.readFromBuffer(shapeFile, buffer); } finally { // Move to the end of the record. buffer.position(pos + this.contentLengthInBytes + RECORD_HEADER_LENGTH); } } /** * Returns the shapefile containing this record. * * @return the shapefile containing this record. */ public Shapefile getShapeFile() { return this.shapeFile; } /** * Returns the zero-orgin ordinal position of the record in the shapefile. * * @return the record's ordinal position in the shapefile. */ public int getRecordNumber() { return this.recordNumber; } /** * Returns the record's shape type. * * @return the record' shape type. See {@link Shapefile} for a list of the defined shape types. */ public String getShapeType() { return this.shapeType; } /** * Returns the record's attributes. * * @return the record's attributes. */ public DBaseRecord getAttributes() { return this.attributes; } /** * Specifies the shapefile's attributes. * * @param attributes the shapefile's attributes. May be null. */ public void setAttributes(DBaseRecord attributes) { this.attributes = attributes; } /** * Returns the number of parts in the record. * * @return the number of parts in the record. */ public int getNumberOfParts() { return this.numberOfParts; } /** * Returns the first part number in the record. * * @return the first part number in the record. */ public int getFirstPartNumber() { return this.firstPartNumber; } /** * Returns the last part number in the record. * * @return the last part number in the record. */ public int getLastPartNumber() { return this.firstPartNumber + this.numberOfParts - 1; } /** * Returns the number of points in the record. * * @return the number of points in the record. */ public int getNumberOfPoints() { return this.numberOfPoints; } /** * Returns the number of points in a specified part of the record. * * @param partNumber the part number for which to return the number of points. * @return the number of points in the specified part. */ public int getNumberOfPoints(int partNumber) { if (partNumber < 0 || partNumber >= this.getNumberOfParts()) { String message = Logging.getMessage("generic.indexOutOfRange", partNumber); Logging.logger().severe(message); throw new IllegalArgumentException(message); } int shapefilePartNumber = this.getFirstPartNumber() + partNumber; return this.getShapeFile().getPointBuffer().subBufferSize(shapefilePartNumber); } /** * Returns the {@link gov.nasa.worldwind.util.VecBuffer} holding the X and Y points of a specified * part. * * @param partNumber the part for which to return the point buffer. * @return the buffer holding the part's points. The points are ordered X0,Y0,X1,Y1,...Xn-1,Yn-1, * where "n" is the number of points in the part. */ public VecBuffer getPointBuffer(int partNumber) { if (partNumber < 0 || partNumber >= this.getNumberOfParts()) { String message = Logging.getMessage("generic.indexOutOfRange", partNumber); Logging.logger().severe(message); throw new IllegalArgumentException(message); } int shapefilePartNumber = this.getFirstPartNumber() + partNumber; return this.getShapeFile().getPointBuffer().subBuffer(shapefilePartNumber); } /** * Returns the {@link gov.nasa.worldwind.util.CompoundVecBuffer} holding all the X and Y points * for this record. The returned buffer contains one sub-buffer for each of this record's parts. * The coordinates for each part are referenced by invoking {@link * gov.nasa.worldwind.util.CompoundVecBuffer#subBuffer(int)}, where the index is one of this * record's part IDs, starting with 0 and ending with <code>{@link #getNumberOfParts()} - 1</code> * (inclusive). * * @return a CompoundVecBuffer that holds this record's coordinate data. */ public CompoundVecBuffer getCompoundPointBuffer() { return this.getShapeFile() .getPointBuffer() .slice(this.getFirstPartNumber(), this.getLastPartNumber()); } /** * Reads and parses subclass-specific contents of a shapefile record from a specified buffer. The * buffer's current position must be the start of the subclass' unique contents and will be the * start of the next record when the constructor returns. * * @param shapefile the containing {@link Shapefile}. * @param buffer the shapefile record {@link java.nio.ByteBuffer} to read from. */ protected abstract void doReadFromBuffer(Shapefile shapefile, ByteBuffer buffer); /** * Reads and parses the contents of a shapefile record from a specified buffer. The buffer's * current position must be the start of the record and will be the start of the next record when * the constructor returns. * * @param shapefile the containing {@link Shapefile}. * @param buffer the shapefile record {@link java.nio.ByteBuffer} to read from. */ protected void readFromBuffer(Shapefile shapefile, ByteBuffer buffer) { // Read record number and record length - big endian. buffer.order(ByteOrder.BIG_ENDIAN); this.recordNumber = buffer.getInt(); this.contentLengthInBytes = buffer.getInt() * 2; // Read shape type - little endian buffer.order(ByteOrder.LITTLE_ENDIAN); int type = buffer.getInt(); String shapeType = shapefile.getShapeType(type); this.validateShapeType(shapefile, shapeType); this.shapeType = shapeType; this.shapeFile = shapefile; this.doReadFromBuffer(shapefile, buffer); } /** * Verifies that the record's shape type matches the expected one, typically that of the * shapefile. All non-null records in a Shapefile must be of the same type. Throws an exception if * the types do not match and the shape type is not <code>{@link Shapefile#SHAPE_NULL}</code>. * Records of type <code>SHAPE_NULL</code> are always valid, and may appear in any Shapefile. * * <p>For details, see the ESRI Shapefile specification at <a * href="http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf"/>, pages 4 and 5. * * @param shapefile the shapefile. * @param shapeType the record's shape type. * @throws WWRuntimeException if the shape types do not match. * @throws IllegalArgumentException if the specified shape type is null. */ protected void validateShapeType(Shapefile shapefile, String shapeType) { if (shapeType == null) { String message = Logging.getMessage("nullValue.ShapeType"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (!shapeType.equals(shapefile.getShapeType()) && !shapeType.equals(Shapefile.SHAPE_NULL)) { String message = Logging.getMessage("SHP.UnsupportedShapeType", shapeType); Logging.logger().severe(message); throw new WWRuntimeException(message); } } /** * Indicates whether the record is a shape type capable of containing optional measure values. * Does not indicate whether the record actually contains measure values. * * @return true if the record may contain measure values. */ protected boolean isMeasureType() { return Shapefile.isMeasureType(this.getShapeType()); } /** * Indicates whether the record is a shape type containing Z values. * * @return true if the record is a type containing Z values. */ protected boolean isZType() { return Shapefile.isZType(this.getShapeType()); } /** * Returns whether the record's point coordinates should be normalized. * * @return <code>true</code> if the record's points should be normalized; <code>false</code> * otherwise. */ public boolean isNormalizePoints() { return this.normalizePoints; } /** * Specifies if the record's point coordinates should be normalized. Defaults to <code>false * </code>. * * @param normalizePoints <code>true</code> if the record's points should be normalized; <code> * false</code> otherwise. */ public void setNormalizePoints(boolean normalizePoints) { this.normalizePoints = normalizePoints; } public void exportAsXML(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException { if (xmlWriter == null) { String message = Logging.getMessage("Export.UnsupportedOutputObject"); Logging.logger().warning(message); throw new IllegalArgumentException(message); } xmlWriter.writeStartElement("Record"); xmlWriter.writeAttribute("id", Integer.toString(this.getRecordNumber())); xmlWriter.writeAttribute( "shape", this.getShapeType().substring(this.getShapeType().lastIndexOf("Shape") + 5)); xmlWriter.writeAttribute("parts", Integer.toString(this.getNumberOfParts())); xmlWriter.writeAttribute("points", Integer.toString(this.getNumberOfPoints())); xmlWriter.writeCharacters("\n"); for (Map.Entry<String, Object> a : this.getAttributes().getEntries()) { xmlWriter.writeStartElement("Attribute"); xmlWriter.writeAttribute("name", a.getKey() != null ? a.getKey().toString() : ""); xmlWriter.writeAttribute("value", a.getValue() != null ? a.getValue().toString() : ""); xmlWriter.writeEndElement(); // Attribute xmlWriter.writeCharacters("\n"); } if (this.getNumberOfParts() > 0) { VecBuffer vb = this.getPointBuffer(0); for (LatLon ll : vb.getLocations()) { xmlWriter.writeStartElement("Point"); xmlWriter.writeAttribute("x", Double.toString(ll.getLatitude().degrees)); xmlWriter.writeAttribute("y", Double.toString(ll.getLongitude().degrees)); xmlWriter.writeEndElement(); // Point xmlWriter.writeCharacters("\n"); } } // TODO: export record-type specific fields xmlWriter.writeEndElement(); // Record } /** * Export the record as KML. This implementation does nothing; subclasses may override this method * to provide KML export. * * @param xmlWriter Writer to receive KML. * @throws IOException If an exception occurs while writing the KML * @throws XMLStreamException If an exception occurs while exporting the data. */ public void exportAsKML(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {} public void printInfo(boolean printCoordinates) { System.out.printf( "%d, %s: %d parts, %d points", this.getRecordNumber(), this.getShapeType(), this.getNumberOfParts(), this.getNumberOfPoints()); for (Map.Entry<String, Object> a : this.getAttributes().getEntries()) { if (a.getKey() != null) System.out.printf(", %s", a.getKey()); if (a.getValue() != null) System.out.printf(", %s", a.getValue()); } System.out.println(); System.out.print("\tAttributes: "); for (Map.Entry<String, Object> entry : this.getAttributes().getEntries()) { System.out.printf("%s = %s, ", entry.getKey(), entry.getValue()); } System.out.println(); if (!printCoordinates) return; VecBuffer vb = this.getPointBuffer(0); for (LatLon ll : vb.getLocations()) { System.out.printf("\t%f, %f\n", ll.getLatitude().degrees, ll.getLongitude().degrees); } } }