protected void buildTextPrimitives(
      VPFCoverage coverage, VPFTile tile, VPFPrimitiveData primitiveData) {
    VPFBufferedRecordData textTable =
        this.createPrimitiveTable(coverage, tile, VPFConstants.TEXT_PRIMITIVE_TABLE);
    if (textTable == null || textTable.getNumRecords() == 0) return;

    int numText = textTable.getNumRecords();
    VPFPrimitiveData.BasicPrimitiveInfo[] textInfo =
        new VPFPrimitiveData.BasicPrimitiveInfo[numText];
    VecBufferSequence coords =
        (VecBufferSequence) textTable.getRecordData("shape_line").getBackingData();
    CompoundStringBuilder strings =
        (CompoundStringBuilder) textTable.getRecordData("string").getBackingData();

    for (VPFRecord row : textTable) {
      int id = row.getId();

      textInfo[VPFBufferedRecordData.indexFromId(id)] =
          new VPFPrimitiveData.BasicPrimitiveInfo(
              VPFBoundingBox.fromVecBuffer(coords.subBuffer(id)));
    }

    primitiveData.setPrimitiveInfo(VPFConstants.TEXT_PRIMITIVE_TABLE, textInfo);
    primitiveData.setPrimitiveCoords(VPFConstants.TEXT_PRIMITIVE_TABLE, coords);
    primitiveData.setPrimitiveStrings(VPFConstants.TEXT_PRIMITIVE_TABLE, strings);
  }
  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 boolean buildNodePrimitives(
      VPFBufferedRecordData table, String name, VPFPrimitiveData primitiveData) {
    int numNodes = table.getNumRecords();
    VPFPrimitiveData.BasicPrimitiveInfo[] nodeInfo =
        new VPFPrimitiveData.BasicPrimitiveInfo[numNodes];
    VecBufferSequence coords =
        (VecBufferSequence) table.getRecordData("coordinate").getBackingData();

    for (VPFRecord row : table) {
      int id = row.getId();

      nodeInfo[VPFBufferedRecordData.indexFromId(id)] =
          new VPFPrimitiveData.BasicPrimitiveInfo(
              VPFBoundingBox.fromVecBuffer(coords.subBuffer(id)));
    }

    primitiveData.setPrimitiveInfo(name, nodeInfo);
    primitiveData.setPrimitiveCoords(name, coords);
    return true;
  }