/** * Given a row from the ring primitive table, navigate the ring and edge primitive tables to * construct a new {@link VPFPrimitiveData.Ring}. * * @param row the ring primitive row. * @param edgeInfoArray the edge primitive data. * @return a new Ring. */ protected VPFPrimitiveData.Ring buildRing( VPFRecord row, VPFPrimitiveData.PrimitiveInfo[] edgeInfoArray) { int faceId = ((Number) row.getValue("face_id")).intValue(); int startEdgeId = ((Number) row.getValue("start_edge")).intValue(); VPFWingedEdgeTraverser traverser = new VPFWingedEdgeTraverser(); // Traverse the ring to collect the number of edges which define the ring. final int numEdges = traverser.traverseRing(faceId, startEdgeId, edgeInfoArray, null); final int[] idArray = new int[numEdges]; final int[] orientationArray = new int[numEdges]; // Traverse the ring again, but this time populate an entry for the primitiveID and orientation // data stuctures // for each edge. traverser.traverseRing( faceId, startEdgeId, edgeInfoArray, new VPFWingedEdgeTraverser.EdgeTraversalListener() { public void nextEdge(int index, int primitiveId, boolean reverseCoordinates) { idArray[index] = primitiveId; orientationArray[index] = reverseCoordinates ? -1 : 1; } }); return new VPFPrimitiveData.Ring(numEdges, idArray, orientationArray); }
/** * Returns the extent ("xmin", "ymin", "xmax", "ymax") for the specified row as a {@link * VPFBoundingBox}. * * @param record the record to extract the bound attributes from. * @return extent of the specified row. */ public static VPFBoundingBox getExtent(VPFRecord record) { if (record == null) { String message = Logging.getMessage("nullValue.RecordIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } return new VPFBoundingBox( ((Number) record.getValue("xmin")).doubleValue(), ((Number) record.getValue("ymin")).doubleValue(), ((Number) record.getValue("xmax")).doubleValue(), ((Number) record.getValue("ymax")).doubleValue()); }
protected static boolean isEdgeOnTileBoundary(VPFRecord record) { VPFTripletId id = null; Object o = record.getValue("left_face"); if (o instanceof VPFTripletId) id = (VPFTripletId) o; if (id == null) { o = record.getValue("right_face"); if (o instanceof VPFTripletId) id = (VPFTripletId) o; } return id != null && id.getExtId() > 0; }
public static void checkAndSetValue( VPFRecord record, String paramName, String paramKey, AVList params) { if (record == null) { String message = Logging.getMessage("nullValue.RecordIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (paramName == null) { String message = Logging.getMessage("nullValue.ParameterNameIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (paramKey == null) { String message = Logging.getMessage("nullValue.ParameterKeyIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (params == null) { String message = Logging.getMessage("nullValue.ParamsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (record.hasValue(paramName)) { Object o = record.getValue(paramName); if (o != null) params.setValue(paramKey, o); } }
protected void buildEdgePrimitives( VPFCoverage coverage, VPFTile tile, VPFPrimitiveData primitiveData) { VPFBufferedRecordData edgeTable = this.createPrimitiveTable(coverage, tile, VPFConstants.EDGE_PRIMITIVE_TABLE); if (edgeTable == null || edgeTable.getNumRecords() == 0) return; VPFBufferedRecordData mbrTable = this.createPrimitiveTable(coverage, tile, VPFConstants.EDGE_BOUNDING_RECTANGLE_TABLE); if (mbrTable == null) return; int numEdges = edgeTable.getNumRecords(); VPFPrimitiveData.EdgeInfo[] edgeInfo = new VPFPrimitiveData.EdgeInfo[numEdges]; VecBufferSequence coords = (VecBufferSequence) edgeTable.getRecordData("coordinates").getBackingData(); for (VPFRecord row : edgeTable) { int id = row.getId(); VPFRecord mbrRow = mbrTable.getRecord(id); edgeInfo[VPFBufferedRecordData.indexFromId(id)] = new VPFPrimitiveData.EdgeInfo( getNumber(row.getValue("edge_type")), getId(row.getValue("start_node")), getNumber(row.getValue("end_node")), getId(row.getValue("left_face")), getId(row.getValue("right_face")), getId(row.getValue("left_edge")), getId(row.getValue("right_edge")), isEdgeOnTileBoundary(row), VPFUtils.getExtent(mbrRow)); } primitiveData.setPrimitiveInfo(VPFConstants.EDGE_PRIMITIVE_TABLE, edgeInfo); primitiveData.setPrimitiveCoords(VPFConstants.EDGE_PRIMITIVE_TABLE, coords); }
protected void buildFacePrimitives( VPFCoverage coverage, VPFTile tile, VPFPrimitiveData primitiveData) { VPFBufferedRecordData faceTable = this.createPrimitiveTable(coverage, tile, VPFConstants.FACE_PRIMITIVE_TABLE); if (faceTable == null) return; VPFBufferedRecordData mbrTable = this.createPrimitiveTable(coverage, tile, VPFConstants.FACE_BOUNDING_RECTANGLE_TABLE); if (mbrTable == null) return; VPFBufferedRecordData ringTable = this.createPrimitiveTable(coverage, tile, VPFConstants.RING_TABLE); if (ringTable == null) return; VPFPrimitiveData.PrimitiveInfo[] edgeInfo = primitiveData.getPrimitiveInfo(VPFConstants.EDGE_PRIMITIVE_TABLE); int numFaces = faceTable.getNumRecords(); VPFPrimitiveData.FaceInfo[] faceInfo = new VPFPrimitiveData.FaceInfo[numFaces]; for (VPFRecord faceRow : faceTable) { int faceId = faceRow.getId(); VPFRecord mbrRow = mbrTable.getRecord(faceId); // Face ID 1 is reserved for the "universe face", which does not have any associated geometry. if (faceId == 1) continue; // The first ring primitive associated with the face primitive defines the outer ring. The // face primitive must // at least contain coordinates for an outer ring. int ringId = ((Number) faceRow.getValue("ring_ptr")).intValue(); VPFRecord ringRow = ringTable.getRecord(ringId); VPFPrimitiveData.Ring outerRing = this.buildRing(ringRow, edgeInfo); // The ring table maintains an order relationship for its rows. The first record of a new face // id will always // be defined as the outer ring. Any repeating records with an identical face value will // define inner rings. ArrayList<VPFPrimitiveData.Ring> innerRingList = new ArrayList<VPFPrimitiveData.Ring>(); for (ringId = ringId + 1; ringId <= ringTable.getNumRecords(); ringId++) { ringRow = ringTable.getRecord(ringId); // Break on the first ring primitive row which isn't associated with the face. Because the // ring rows // maintain an ordering with respect to face id, there will be no other ring rows // corresponding to this // face. if (faceId != getId(ringRow.getValue("face_id"))) break; VPFPrimitiveData.Ring innerRing = this.buildRing(ringRow, edgeInfo); if (innerRing != null) innerRingList.add(innerRing); } VPFPrimitiveData.Ring[] innerRings = new VPFPrimitiveData.Ring[innerRingList.size()]; innerRingList.toArray(innerRings); faceInfo[VPFBufferedRecordData.indexFromId(faceId)] = new VPFPrimitiveData.FaceInfo(outerRing, innerRings, VPFUtils.getExtent(mbrRow)); } primitiveData.setPrimitiveInfo(VPFConstants.FACE_PRIMITIVE_TABLE, faceInfo); }