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.打开⼀个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_object和get_next_owned_object返回的块对象的属性依次处理每个对象,如 。
清单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-&ity->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>
}
该库的先决条件是autoconf , swig , texinfo和python-dev软件包以及编译器软件包(如果使⽤Debian或Ubuntu,则为build-essential )。 您可以通过在命令⾏中输⼊以下内容来下载来构建库:
git clone git://u.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程序员指南链接 ),但你只关⼼在⼤多数情况下,通常,少数addPoint ,addLine , addCircle和addVertex 。 您只需要实现您关⼼的功能即可; 其余的您可以忽略。 显⽰了⼀个简单的⽰例,该⽰例加载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 。 最后,该⾏在调⽤endEntity或endBlock时结束,这时您具有完整的⾏并可以呈现它,将其导出为新格式或执⾏其他操作。
您只需在命令⾏中输⼊以下内容即可构建和安装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⽂件。 阅读这些格式时,建议使⽤诸如Xerce
s-C ++之类的形式库来处理您可能遇到的更复杂的结构。 编写时,通常只需使⽤简单的内置语⾔功能就可以编写⽂本⽂件,然后⾃⼰⽣成适当的⽂本。
基本的KML⽂件由“ Document部分组成,其中包含名称和描述。 该⽂件可能还包含⼀个或多个⽂件夹(⽤于逻辑组织形状),并且每个⽂件夹内都有地标。 地标是实际的形状,您可以将其定义为LineString,Point,Polygon或其他类型。 编写KML⽂件需要编写格式正确的表⽰形状的⽂本,如所⽰。
清单4.⼀个简单的KML⽂件
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="www.opengis/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)的⼀部分)轻松访问这些⽂件。 在⽰例转换器中,您仅需要输出,但是此库还简化了读取形状数据的过程。 写⼊数据需要打开输出数据源并在其中创建数据层。 您可以创建字段以存储每种形状的⾮空间数据。 创建输出数据源之后,可以向数据源添加多个形状(称为特征 )。 创建要素需要您还创建⼀个⼏何图形(例如点或线),并将其与要素相关联。 该功能充当所有场/⾮空间和⼏何数据的容器。
显⽰了⽤于创建新shapefile数据源和数据集中的单个点的代码。 见OGR C++读/写教程和OGR类层次结构和⽂档链接在的更多信息,使⽤OGR和⼀个下载链接库本⾝。 ⼤多数Linux®发⾏版存储库都包括GDAL库和头⽂件libgdal1-1.7.0和libgdal1-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");
什么软件能打开dwg文件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的命令⾏转换器
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论