autocad形源代码_在开放源代码库中使用AutoCAD文件格式

autocad形源代码

许多开发人员和地理信息系统(GIS)专业人员无法使用图形交换格式(DXF)或“图形”(DWG)文件。 这些AutoCAD格式通常要求您具有Windows®和AutoCAD副本才能打开它们。 使用一些方便的开源库,您可以使您的应用程序能够免费读取任何操作系统上的DXF和DWG文件。 在本文中,您将构建一个转换器,将这些文件格式转换为更开放的ESRI shapefile或锁Kong标记语言(KML)格式。 商业和开源软件使用ESRI Shapefile,而Google Earth和Google Maps主要使用KML。

AutoCAD DWG和LibreDWG

最常见的AutoCAD格式是“绘图”格式,文件扩展名以.dwg结尾。 很少有软件应用程序可以读取此格式,这是在AutoCAD中保存文件时的默认格式。 但是,您可以使用开源库LibreDWG(参见相关主题 )来读取这些文件。 文件格式由一个控制块组成,该控制块包含表示文件中形状的其他块,以及用于模型空间和图纸空间的块,这些模型空间和图纸空间表示文档中坐标的偏移量。

您可以通过打开文档并读取文件来使用库,然后遍历主控制块中的每个块,如清单1所示。

清单1.打开一个DWG文件并遍历主控制块
Dwg_Data dwg = new Dwg_Data();
int errno = dwg_read_file((char *)inputFilename, dwg);
if (errno) {
  fprintf(stderr, "Could not open DWG. Returned error code: $d\n", errno);
  delete dwg;
}

Dwg_Object_BLOCK_CONTROL * ctrl = dwg->object[0].tio.object->tio.BLOCK_CONTROL;
dumpBlock(ctrl->model_space);
dumpBlock(ctrl->paper_space);	

for (int i = 0; i < ctrl->num_entries; i++) {
  dumpBlock(ctrl->block_headers[i]);
}	
dwg_free(dwg);

每个块可以代表几种几何类型中的任何一种:直线,圆,弧,锚定到某个位置的文本或插入(将偏移量应用于以后的块)。 您可以通过访问get_first_owned_objectget_next_owned_object返回的块对象的属性依次处理每个对象,如清单2所示

清单2.使用get_first_owned_object和get_next_owned_object读取对象
void InputFormatDWG::dumpBlock(Dwg_Object_Ref * block) {
  if (!block) return;
  if (!block->obj) return;
  if (!block->obj->tio.object) return;

  Dwg_Object_BLOCK_HEADER * header = block->obj->tio.object->tio.BLOCK_HEADER;
  Dwg_Object * obj = get_first_owned_object(block->obj, header);
  while (obj) {
    if (obj->type == DWG_TYPE_LINE) {
      Dwg_Entity_LINE * line = obj->tio.entity->tio.LINE;
      printf("Line starting at (%f, %f, %f) ending at (%f, %f, %f)\n", line->start.x, 
              line->start.y, 0, line->end.x, line->end.y, 0);
      // Don't delete "line" - dwg_free will do this
    }

    obj = get_next_owned_object(block->obj, obj, header);
  }
}

这样,从头到尾使用LibreDWG读取DWG文件是一个顺序流程。 在C++实现LibreDWG时,将dwg.h包含在extern "C"块中非常重要,以避免以后遇到链接器错误。 这是一个例子:

extern "C" {
	#include <dwg.h>
}

该库的先决条件是autoconfswigtexinfopython-dev软件包以及编译器软件包(如果使用Debian或Ubuntu,则为build-essential )。 您可以通过在命令行中输入以下内容来下载来构建库:

git clone git://git.sv.gnu.org/libredwg.git

。 。 。 其次是:

./autogen.sh && ./configure && make && sudo make install

AutoCAD DXF和dxflib

DXF格式是AutoCAD内部的导出选项。 这样,支持DWG的应用程序比支持DWG的应用程序更多,并且文件格式规范已发布( 有关完整DXF规范的链接,请参阅参考资料)。 但是,您可以使用开源dxflib库读取这些文件。 与LibreDWG不同,读取DXF文件的驱动程序由您自己的顺序编码驱动。 实际上,使用dxflib就像编写事件驱动的代码。

您可以通过调用DL_Dxf对象的in函数并将指针传递给从DL_CreationAdapter抽象类继承的类来打开文件。 当in函数运行时,它将在传递给它的类中调用几个函数。 有几十个这样的功能(见DXFLib程序员指南链接相关信息 ),但你只关心在大多数情况下,通常,少数addPointaddLineaddCircleaddVertex 。 您只需要实现您关心的功能即可; 其余的您可以忽略。 清单3显示了一个简单的示例,该示例加载DXF文件并仅读取其中的行。

清单3.加载DXF文件并只读行
LineReader.h:
#ifndef LINEREADER_H
#define LINEREADER_H

#include "dxflib/src/dl_dxf.h"
#include "dxflib/src/dl_creationadapter.h"
#include <stdio.h>

class LineReader: public DL_CreationAdapter {
	public:
		// Our functions:
		void readLines(const char * filename);

		// Overloading from parent DL_CreationAdapter:
		void addLine(const DL_LineData& data);


};
#endif

LineReader.cpp:
void LineReader::readLines(const char * filename) {
  DL_Dxf * getData = new DL_Dxf();
  if (!getData->in(filename, this)) {
    fprintf(stderr, "Could not retrieve data from input file.\n");
    delete getData;
    exit(1);
  }  
  delete getData;
}

void LineReader::addLine(const DL_LineData& data) {
  printf("Line starting at (%f, %f, %f) ending at (%f, %f, %f)\n", 
          data.x1, data.y1, data.z1, data.x2, data.y2, data.z2);
}

像DWG一样,DXF格式可以包含inserts ,它们表示要应用于插入后遇到的几何特征的偏移量。 这些插入物必须存储在内部,并在遇到它们时应用于坐标。 同样,添加折线 (具有多个顶点的线)需要存储一些数据。 该库首先调用addPolyline ,指示一行即将到来。 然后为该行的每个顶点调用一次addVertex 。 最后,该行在调用endEntityendBlock时结束,这时您具有完整的行并可以呈现它,将其导出为新格式或执行其他操作。

您只需在命令行中输入以下内容即可构建和安装DXF库:

./configure && make && sudo make install

您可能会收到有关strcasecmp以及未声明strlen错误消息。 dxflib库是使用GCC / G ++ 4.2构建的,在4.3版中,头文件进行了一些重组。 要解决此错误,需要在src / dl_writer.h和src / dl_writer_ascii.h以及#include <cstring>#include <cstdlib>的其他包含项附近添加一些包含项。

注:这些变化已经对副本所做的dxflib包含在可用的转换器的源代码下载 ,前提是您必须下载此更改应用dxflib从直接dxflib网站。

KML和纯文本/ Xerces-C ++

Google Earth和Google Maps使用的KML格式是XML的一种特殊形式。 这样,您可以使用Xerces-C ++ XML Parser之类的库(请参阅参考资料中的链接)来处理KML文件。 阅读这些格式时,建议使用诸如Xerces-C ++之类的形式库来处理您可能遇到的更复杂的结构。 编写时,通常只需使用简单的内置语言功能就可以编写文本文件,然后自己生成适当的文本。

基本的KML文件由“ Document部分组成,其中包含名称和描述。 该文件可能还包含一个或多个文件夹(用于逻辑组织形状),并且每个文件夹内都有地标。 地标是实际的形状,您可以将其定义为LineString,Point,Polygon或其他类型。 编写KML文件需要编写格式正确的表示形状的文本,如清单4所示。

清单4.一个简单的KML文件
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
  <name>test</name>
  <open>1</open>
  <description>Converted from AutoCAD DXF or DWG</description>
  <Folder>
    <name>test</name>
    <Placemark>
      <LineString>
        <tessellate>0</tessellate>
        <coordinates>27.54998,82.27393,0.00000 39.72346,9.25601,0.00000</coordinates>
      </LineString>
    </Placemark>
  </Folder>
</Document>
</kml>

您可能还会遇到KMZ文件,它们只是用ZIP压缩压缩的KML文件。 请参阅相关信息的链接,对KML初学者教程和完整的KML文件。

ESRI Shapefile和GDAL / OGR

shapefile格式是ESRI发布的商业(但开放的)二进制数据格式( 有关完整技术说明的链接,请参阅参考资料)。 您可以使用开源OGR简单要素库(地理空间数据抽象层(GDAL)的一部分)轻松访问这些文件。 在示例转换器中,您仅需要输出,但是此库还简化了读取形状数据的过程。 写入数据需要打开输出数据源并在其中创建数据层。 您可以创建字段以存储每种形状的非空间数据。 创建输出数据源之后,可以向数据源添加多个形状(称为特征 )。 创建要素需要您还创建一个几何图形(例如点或线),并将其与要素相关联。 该功能充当所有场/非空间和几何数据的容器。

清单5显示了用于创建新shapefile数据源和数据集中的单个点的代码。 见OGR C++读/写教程和OGR类层次结构和文档链接在相关主题的更多信息,使用OGR和一个下载链接库本身。 大多数Linux®发行版存储库都包括GDAL库和头文件libgdal1-1.7.0libgdal1-dev (版本可能有所不同)。

清单5.创建一个带有单个点的shapefile
OGRRegisterAll();
OGRSFDriver drv = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("ESRI Shapefile");
if (drv == NULL) {
  fprintf(stderr, "Could not open Shapefile OGR driver.\n");
  return;
}  

OGRDataSource ds = drv->CreateDataSource(filename, NULL);
if (ds == NULL) {
  fprintf(stderr, "Could not create output file.\n");
  return;
}

OGRLayer lyr = ds->CreateLayer("Layer", NULL, wkbPoint, NULL);
if (lyr == NULL) {
  fprintf(stderr, "Could not create layer.\n");
  return;
}

// Add an ID field
OGRFieldDefn newField("id", OFTInteger);
newField.SetWidth(32);
lyr->CreateField(&newField);

if (!lyr) {
  fprintf(stderr, "No output layer is available.");
  return;
}
  
OGRFeature * newFeat = OGRFeature::CreateFeature(lyr->GetLayerDefn());
newFeat->SetField("id", lyr->GetFeatureCount(1));
OGRPoint point;
point.setX(15.653);
point.setY(43.783);
point.setZ(0);
newFeat->SetGeometry(&point);
lyr->CreateFeature(newFeat);
  
// Clean up your memory
OGRFeature::DestroyFeature(newFeat);

if (ds) {
  // Will trigger saving the file and also 
  // clean up any layer references from Create/Get Layer calls
  OGRDataSource::DestroyDataSource(ds);
}

实现文件格式库

在软件中实现文件格式库的主要方法有三种。 第一种方法(应用程序中的本机实现)要求您能够直接使用代码中的库,这意味着您可能必须使用特定的语言集来编写代码,具体取决于绑定的可用性。 它还需要一些牢固的链接,更新库版本时可能会导致较小的错误。 但是,在您的应用程序中直接实现确实会使用户感觉使用格式更加流畅。

另一种方法是为您的应用程序编写插件或扩展,以提供对所需文件格式的支持。 此方法使您在文件格式库和应用程序代码之间有一定程度的分离。 如果您的应用程序已经有一个插件框架,这可能是一个不错的选择。 例如,普通的桌面GIS应用程序Quantum GIS使用插件体系结构。 一个这样的插件使您可以直接在应用程序中使用分隔的文本文件。

可以创建最后一个也是最简单的方法-独立转换器-在两种或多种文件格式之间进行转换。 这项技术的优点是无论您的数据最终目标是什么,都可以重用,但要为用户增加另一步。

DXF / DWG到KML / Shapefile的命令行转换器

在此示例中,您将采用创建文件格式转换器的更简单且可重用的途径。 您的目标是创建一个易于扩展的转换器,以处理其他格式,并使任何特定输入或输出格式的逻辑尽可能分开。 这些目标导致了两个抽象类的定义: InputFormatOutputFormat (请参见清单6 )。

清单6. InputFormat和OutputFormat抽象类定义
OutputFormat.h:
#ifndef OUTPUTFORMAT_H
#define OUTPUTFORMAT_H

#include "OutputFormatTypes.h"
#include <vector>

class OutputFormat {
  public:
    OutputFormat() {};
    ~OutputFormat() {};

    // Standard feature types:
    virtual void addPoint(OutputFeaturePoint newPoint) = 0;
    virtual void addLine(OutputFeatureLine newLine) = 0;
    virtual void addPolyLine(std::vector<OutputFeaturePoint *> newPoints) = 0;
    virtual void addPolygon(std::vector<OutputFeaturePoint *> newPoints) = 0;

    // For approximating text on DXF/DWG with a separate point layer with
    // a label attribute:
    virtual void addText(OutputFeaturePoint location, const char * text) = 0;

    // The cleanup function
    virtual void finalizeOutput() = 0;
};
#endif

InputFormat.h:
#ifndef INPUTFORMAT_H
#define INPUTFORMAT_H

#include "OutputFormat.h"

class InputFormat {
  public:
    InputFormat() {};
    ~InputFormat() {};
    virtual void readFeaturesInto(OutputFormat * outputHandler) = 0; 
};
#endif

您实现的任何格式都必须从这些类之一继承。 这样,程序的主要功能和入口点可以专门处理确定要实例化的类。 定义输入文件和输出文件后,可以用单行代码进行转换:

input->readFeaturesInto(output);

然后,主要函数的作用(请参见清单7 )变成仅实例化正确的输入和输出格式,最终达到readFeaturesInto函数调用。

清单7. AutoCAD转换器的main()函数
void usage(char * me) {
  printf("Usage: %s inputfile outputfile [point|line|polygon]\n", me);
  printf("Input formats supported:\n");
  printf("\tAutoCAD DXF (*.dxf)\n");
  printf("\tAutoCAD DWG (*.dwg)\n");
  printf("Output formats supported:\n");
  printf("\tText (*.txt)\n");
  printf("\tESRI Shapefile (*.shp)\n");
  printf("\tKeyhold Markup Language (*.kml)\n");
  printf("\nInput format and output format are determined automatically by file extension.
		  \n");
  printf("If you use a shapefile as the output format, please additionally specify\n");
  printf("point, line, or polygon output shapefile type.\n");
}

int main(int argc, char * argv[]) {
  if (argc < 3) {
    usage(argv[0]);
    return 1;
  }

  OutputFormat * output = NULL;  
  InputFormat * input = NULL;
  struct stat fileExists;

  // Set up output format first...
  std::string outFile = argv[2];
  if (outFile.rfind('.') == std::string::npos) {
    printf("I couldn't make sense of your output filename's extension: %s. Please use 
            filename.shp, filename.kml, or filename.txt.\n", argv[2]);
    return 1;
  }
  if (outFile.substr(outFile.rfind('.')+1) == "txt") {
    printf("Setting up output file %s...\n", argv[2]);
    output = new OutputFormatText(argv[2]);
  }
  else if (outFile.substr(outFile.rfind('.')+1) == "shp") {
    if (argc < 4) {
      printf("When specifying shapefile output, please also specify 'point', 'line', or 
              'polygon'. See usage.\n");
      return 1;
    }
    std::string textAttributeFile = outFile.substr(0, outFile.rfind('.')) + "_text.shp";
    OGRwkbGeometryType type;
    if (strcmp(argv[3], "line") == 0) {
      type = wkbLineString;
    }
    else if (strcmp(argv[3], "point") == 0) {
      type = wkbPoint;
    }
    else if (strcmp(argv[3], "polygon") == 0) {
      type = wkbPolygon;
    }
    else {
      printf("I didn't understand %s. Please use point, line, or polygon.\n", argv[3]);
      return 1;
    }
    printf("Setting up output file %s...\n", argv[2]);
    output = new OutputFormatSHP(argv[2], textAttributeFile.c_str(), outFile.substr(0, 
                 outFile.rfind('.')).c_str(), type);
  }
  else if (outFile.substr(outFile.rfind('.')+1) == "kml") {
    printf("Setting up output file %s...\n", argv[2]);
    output = new OutputFormatKML(argv[2], outFile.substr(0, outFile.rfind('.')).c_str());
  }

  // Next grab the input file
  std::string inFile = argv[1];
  if (inFile.rfind('.') == std::string::npos) {
    printf("I couldn't make sense of your input filename's extension: %s. Please use 
            filename.dxf or filename.dwg.\n", argv[1]);
    delete output;
    return 1;
  }
  if (stat(argv[1], &fileExists) != 0) {
    printf("The specified input file does not exist or is not accessible: %s\n", argv[1]);
    return 1;
  }
  if (inFile.substr(inFile.rfind('.')+1) == "dxf") {
    input = new InputFormatDXF(argv[1]);
    printf("Setting up input file %s...\n", argv[1]);
  }
  else if (inFile.substr(inFile.rfind('.')+1) == "dwg") {
    input = new InputFormatDWG(argv[1]);
    printf("Setting up input file %s...\n", argv[1]);
  }

  if (!input) {
    printf("The input file was not recognized or could not be opened.\n");
    return 1;
  }
  if (!output) {
    printf("The output file was not recognized or could not be opened.\n");
    return 1;
  }

  printf("Converting file...\n");
  input->readFeaturesInto(output);
  output->finalizeOutput();
  printf("Done!\n");

  delete input;
  delete output;
  return 0;
}

InputFormat类中唯一需要的函数是readFeaturesInto ,这使它向各个输入格式开放,它实际上是如何实际希望为所提供的输出类提供特征(形状)。 但是, OutputFormat类具有一些其他必需的函数-用于添加各种类型的几何形状的函数。 您可以为点和线定义自己的类,以便可以将所有参数提供为双精度值而不是整数,并可以提供z轴。

ESRI Shapefile格式有一个重要限制; 它只能存储单一类型的形状(例如,仅线条,仅点或仅多边形)。 本文讨论的其他格式(DXF,DWG和KML)没有此限制。 在OutputFormatSHP类中,检查以查看要创建哪种shapefile。 如果它不是正确的类型,那么您将尽力而为。 创建点shapefile时,系统提示您添加折线形状时,将每个顶点添加为单个点。 创建线shapefile时,如果提示您添加点,则会向标准错误写入警告,指示该形状已被忽略。 DXF和DWG文件格式还支持圆弧和圆弧,您可以通过创建多个近似圆弧或圆弧的小线段来近似输出格式。

编译示例应用程序时,您可能会收到与dwg.h有关的错误消息。 dxflib和LibreDWG库都定义了全局定义THICKNESS ,因此请在其安装位置(例如/usr/local/include/dwg.h)中编辑dwg.h文件,并更改THICKNESS常量的名称或添加下划线。 ( _ )结尾。 (此示例代码中并未实际使用。)

注意:有关此示例文件格式转换器的完整源代码,请参见“ 下载”部分。

将翻译器包装在网站中

至此,您已经具有用于文件格式的功能齐全的命令行转换器。 但是,大多数通常询问如何读取这些文件的用户既不懂命令行,也不能自己从源代码构建转换器。 然后,有必要为此工具提供一个基于Web的简单网关,以便需要快速转换一个或两个文件的人可以轻松地这样做。 同时,您可以创建一个系统,在该系统中,将文件添加到磁盘上的特定目录后会自动转换文件,可用于FTP交互或通过CIFS文件共享进行访问。

首先,为各种shapefile输出格式类型创建一些目录:

  • 用于KML和文本输出格式的uploads_KML和uploads_Text
  • 各种形状文件输出格式的uploads_Point,uploads_Polyline和uploads_Polygon

惯例是,任何上传到这些位置的DXF或DWG文件都将转换为目录名称所暗示的格式。 输出应放在另一个目录中,称为输出。

有了这样的设置,您可以构造一个简单的BASH Shell脚本(请参见清单8 )来检查该位置的DWG和DXF文件,并使用适当的命令行参数触发转换器。 为了帮助将来进行调试,该脚本还可以将所有上载的输入以及生成的输出保存到带时间戳的.zip文件中,以供管理使用。 您可以将此脚本设置为作为cron作业定期运行,或者作为自动转换器使用FTP和CIFS(Windows文件共享)。

清单8. BASH脚本检查是否有待转换的文件并将其传递给转换器
#!/bin/bash -u

# Polyline Shapefile queue
cd /var/www/acadconverter.chrismichaelis.com/uploads_Polyline
for file in /var/www/acadconverter.chrismichaelis.com/uploads_Polyline/*.d*; do
  [[ "$file" =~ .dxf$ || "$file" =~ dwg$ ]] && {
    base=$(basename "$file")
    base=${base%.dwg}
    base=${base%.dxf}
    /var/www/acadconverter.chrismichaelis.com/bin/AutoCADConverter \
                "$file" "$base.shp" line
    [ -e "../outputs/$base.zip" ] && rm -f "../outputs/$base.zip"
    zip "../outputs/$base.zip" "$base.shx" "$base.shp" "$base.dbf" \
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf"
    zip "../uploads_done/$(date +%s)_$base.zip" "$base.shx" "$base.shp" "$base.dbf" \ 
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf" "$file"
    rm -f "$file" "$base.shx" "$base.shp" "$base.dbf" "${base}_text.shp" \ 
                "${base}_text.shx" "${base}_text.dbf"
  }
done

# Polygon Shapefile queue
cd /var/www/acadconverter.chrismichaelis.com/uploads_Polygon
for file in /var/www/acadconverter.chrismichaelis.com/uploads_Polygon/*.d*; do
  [[ "$file" =~ .dxf$ || "$file" =~ dwg$ ]] && {
    base=$(basename "$file")
    base=${base%.dwg}
    base=${base%.dxf}
    /var/www/acadconverter.chrismichaelis.com/bin/AutoCADConverter "$file" \ 
                "$base.shp" polygon 
    [ -e "../outputs/$base.zip" ] && rm -f "../outputs/$base.zip"
    zip "../outputs/$base.zip" "$base.shx" "$base.shp" "$base.dbf" \ 
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf"
    zip "../uploads_done/$(date +%s)_$base.zip" "$base.shx" "$base.shp" "$base.dbf" \ 
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf" "$file"
    rm -f "$file" "$base.shx" "$base.shp" "$base.dbf" "${base}_text.shp" \ 
                "${base}_text.shx" "${base}_text.dbf"
  }
done

# Point Shapefile queue
cd /var/www/acadconverter.chrismichaelis.com/uploads_Point
for file in /var/www/acadconverter.chrismichaelis.com/uploads_Point/*.d*; do
  [[ "$file" =~ .dxf$ || "$file" =~ dwg$ ]] && {
    base=$(basename "$file")
    base=${base%.dwg}
    base=${base%.dxf}
    /var/www/acadconverter.chrismichaelis.com/bin/AutoCADConverter "$file" \
                "$base.shp" point
    [ -e "../outputs/$base.zip" ] && rm -f "../outputs/$base.zip"
    zip "../outputs/$base.zip" "$base.shx" "$base.shp" "$base.dbf" \  
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf"
    zip "../uploads_done/$(date +%s)_$base.zip" "$base.shx" "$base.shp" "$base.dbf" \ 
                "${base}_text.shp" "${base}_text.shx" "${base}_text.dbf" "$file"
    rm -f "$file" "$base.shx" "$base.shp" "$base.dbf" "${base}_text.shp" \  
                "${base}_text.shx" "${base}_text.dbf"
  }
done

# KML queue
cd /var/www/acadconverter.chrismichaelis.com/uploads_KML
for file in /var/www/acadconverter.chrismichaelis.com/uploads_KML/*.d*; do
  [[ "$file" =~ .dxf$ || "$file" =~ dwg$ ]] && {
    base=$(basename "$file")
    base=${base%.dwg}
    base=${base%.dxf}
    /var/www/acadconverter.chrismichaelis.com/bin/AutoCADConverter "$file" "$base.kml" 
    [ -e "../outputs/$base.zip" ] && rm -f "../outputs/$base.zip"
    zip "../outputs/$base.zip" "$base.kml"
    zip "../uploads_done/$(date +%s)_$base.zip" "$base.kml" "$file"
    rm -f "$file" "$base.kml"
  }
done

# Text queue
cd /var/www/acadconverter.chrismichaelis.com/uploads_Text
for file in /var/www/acadconverter.chrismichaelis.com/uploads_Text/*.d*; do
  [[ "$file" =~ .dxf$ || "$file" =~ dwg$ ]] && {
    base=$(basename "$file")
    base=${base%.dwg}
    base=${base%.dxf}
    /var/www/acadconverter.chrismichaelis.com/bin/AutoCADConverter "$file" "$base.txt" 
    [ -e "../outputs/$base.zip" ] && rm -f "../outputs/$base.zip"
    zip "../outputs/$base.zip" "$base.txt"
    zip "../uploads_done/$(date +%s)_$base.zip" "$base.txt" "$file"
    rm -f "$file" "$base.txt"
  }
done

网站本身可以是一个简单的文件上传页面。 在这种情况下,包括上传进度条将是一个很好的增强。 一个称为Ajax Upload的开源工具(请参阅参考资料中的链接)使用XMLHttpRequest来帮助产生更流畅的上载界面。 在HTML页面中,页面加载后,使用jQuery ready函数创建文件上传器,并将所选的输出格式与上传的文件一起传递(请参见清单9 )。 使用随Ajax Upload工具提供的handleUpload PHP上传脚本,并且在该脚本的末尾,更改了handleUpload命令以将上传的文件保存到所需输出类型的正确目录中。 然后,您不必等待排定的cron作业发生,而是使用exec PHP函数启动脚本并转换文件。 HTML页面将等待片刻以完成转换,然后将访问者定向到包含生成的输出文件的生成的.zip文件。

清单9.设置文件上传器的jQuery ready()函数
$(document).ready(function() {
  var uploader = new qq.FileUploader({
    'element': $('#inputFile')[0],
    'action': 'fileuploader.php',
    'params': { 'outputFormat': $('#outputFormat option:selected').attr('value') },
    'onComplete': function(id, file, response) {
      if (!response.success) return;
      // Please Wait
      $('#postLoader').hide()
      $('#postLoader').html('<img src="clock.png" height="210" width="210"><br />
                             Please Wait...');
      $('#postLoader').slideDown();

      // for IE compatibility, don't use anonymous function in setTimeout
      setTimeout("showDownload('" + file.replace(".dwg", "").replace(".dxf", "") + "');",
                 5000);
      return true;
    }
  });

  $('#outputFormat').change(function() {
    uploader.setParams({
      'outputFormat': $('#outputFormat option:selected').attr('value')
    });
  });
});

function showDownload(file) {
  $('#postLoader').slideUp('slow', function() { $('#postLoader').html('<img 
        src="download.png" height="48" width="48" align="absmiddle"> 
        <a href="outputs/' + file + '.zip">Download Ouptut</a>').slideDown(); });
}

此代码极大地简化了转换器,从而实现了使任何需要转换文件的人都可以轻松访问的目标。 请参阅相关信息的链接,完成网络接口转换器,或参阅下载完整的源代码部分的转换网页。

结论

您可以在此示例中扩展简单文件格式转换器,以处理更多几何和地理数据文件格式。 您可以使用此处演示的库来扩展任何软件工具,以本机处理这些文件格式。 除了此处演示的C++用法和语法外,这些库的绑定还可用多种语言提供。

翻译自: https://www.ibm.com/developerworks/opensource/library/os-autocad/index.html

autocad形源代码

    原文作者:cuxiong8996
    原文地址: https://blog.csdn.net/cuxiong8996/article/details/107153573
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞