1 /* **************************************************************
2 *
3 * MODULE: v.in.dwg
4 *
5 * AUTHOR(S): Radim Blazek
6 *
7 * PURPOSE: Import of DWG/DXF files
8 *
9 * COPYRIGHT: (C) 2001-2008 by the GRASS Development Team
10 *
11 * This program is free software under the
12 * GNU General Public License (>=v2).
13 * Read the file COPYING that comes with GRASS
14 * for details.
15 *
16 * In addition, as a special exception, Radim Blazek gives permission
17 * to link the code of this program with the OpenDWG libraries (or with
18 * modified versions of the OpenDWG libraries that use the same license
19 * as OpenDWG libraries), and distribute linked combinations including the two.
20 * You must obey the GNU General Public License in all respects for all
21 * of the code used other than. If you modify this file, you may extend
22 * this exception to your version of the file, but you are not obligated
23 * to do so. If you do not wish to do so, delete this exception statement
24 * from your version.
25 *
26 * **************************************************************/
27 #define AD_PROTOTYPES
28 #define AD_VM_PC
29 #define OD_GENERIC_READ
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <math.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <grass/gis.h>
38 #include <grass/dbmi.h>
39 #include <grass/vector.h>
40 #include <grass/glocale.h>
41 #include "ad2.h"
42 #include "io/odio.h"
43 #include "global.h"
44
45 int cat;
46 int n_elements; /* number of processed elements (only low level elements) */
47 int n_skipped; /* number of skipped low level elements (different layer name) */
48 struct Map_info Map;
49 dbDriver *driver;
50 dbString sql;
51 dbString str;
52 struct line_pnts *Points;
53 struct line_cats *Cats;
54 PAD_LAY Layer;
55 char *Txt;
56 char *Block;
57 struct field_info *Fi;
58 AD_DB_HANDLE dwghandle;
59 TRANS *Trans; /* transformation */
60 int atrans; /* number of allocated levels */
61 struct Option *layers_opt;
62 struct Flag *invert_flag;
63
main(int argc,char * argv[])64 int main(int argc, char *argv[])
65 {
66 struct GModule *module;
67 struct Option *out_opt, *in_opt;
68 struct Flag *z_flag, *circle_flag, *l_flag, *int_flag;
69 char buf[2000];
70
71 /* DWG */
72 char path[2000];
73 short initerror, entset, retval;
74 AD_OBJHANDLE pspace, mspace;
75 PAD_ENT_HDR adenhd;
76 PAD_ENT aden;
77 AD_VMADDR entlist;
78
79 G_gisinit(argv[0]);
80
81 module = G_define_module();
82 G_add_keyword(_("vector"));
83 G_add_keyword(_("import"));
84 module->description = _("Converts DWG/DXF to GRASS vector map");
85
86 in_opt = G_define_standard_option(G_OPT_F_INPUT);
87 in_opt->description = _("Name of DWG or DXF file");
88
89 out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
90 out_opt->required = YES;
91
92 layers_opt = G_define_option();
93 layers_opt->key = "layers";
94 layers_opt->type = TYPE_STRING;
95 layers_opt->required = NO;
96 layers_opt->multiple = YES;
97 layers_opt->description = _("List of layers to import");
98
99 invert_flag = G_define_flag();
100 invert_flag->key = 'i';
101 invert_flag->description =
102 _("Invert selection by layers (don't import layers in list)");
103
104 z_flag = G_define_flag();
105 z_flag->key = 'z';
106 z_flag->description = _("Create 3D vector map");
107
108 circle_flag = G_define_flag();
109 circle_flag->key = 'c';
110 circle_flag->description = _("Write circles as points (centre)");
111
112 l_flag = G_define_flag();
113 l_flag->key = 'l';
114 l_flag->description = _("List available layers and exit");
115
116 int_flag = G_define_flag();
117 int_flag->key = 'n';
118 int_flag->description = _("Use numeric type for attribute \"layer\"");
119
120 if (G_parser(argc, argv))
121 exit(EXIT_FAILURE);
122
123 db_init_string(&sql);
124 db_init_string(&str);
125 adenhd = (PAD_ENT_HDR) G_malloc(sizeof(AD_ENT_HDR));
126 aden = (PAD_ENT) G_malloc(sizeof(AD_ENT));
127 Layer = (PAD_LAY) G_malloc(sizeof(AD_LAY));
128 Points = Vect_new_line_struct();
129 Cats = Vect_new_cats_struct();
130 Block = NULL;
131
132 atrans = 20; /* nested, recursive levels */
133 Trans = (TRANS *) G_malloc(atrans * sizeof(TRANS));
134
135 /* Init OpenDWG */
136 sprintf(path, "%s/etc/adinit.dat", G_gisbase());
137 if (!adInitAd2(path, &initerror)) {
138 sprintf(buf, _("Unable to initialize OpenDWG Toolkit, error: %d: %s."),
139 initerror, adErrorStr(initerror));
140 if (initerror == AD_UNABLE_TO_OPEN_INIT_FILE)
141 sprintf(buf, _("%s Cannot open %s"), buf, path);
142 G_fatal_error(buf);
143 }
144 adSetupDwgRead();
145 adSetupDxfRead();
146
147 /* Open input file */
148 if ((dwghandle = adLoadFile(in_opt->answer, AD_PRELOAD_ALL, 1)) == NULL) {
149 G_fatal_error(_("Unable to open input file <%s>. Error %d: %s"),
150 in_opt->answer, adError(),
151 adErrorStr(adError()));
152 }
153
154 if (l_flag->answer) { /* List layers */
155 PAD_TB adtb;
156 AD_DWGHDR adhd;
157 int i;
158 char on, frozen, vpfrozen, locked;
159
160 adtb = (PAD_TB) G_malloc(sizeof(AD_TB));
161
162 G_debug(2, "%d layers", (int)adNumLayers(dwghandle));
163 adReadHeaderBlock(dwghandle, &adhd);
164 adStartLayerGet(dwghandle);
165
166 fprintf(stdout, "%d layers:\n", (int)adNumLayers(dwghandle));
167 for (i = 0; i < (int)adNumLayers(dwghandle); i++) {
168 adGetLayer(dwghandle, &(adtb->lay));
169 if (!adtb->lay.purgedflag) {
170 fprintf(stdout, "%s COLOR %d, ", adtb->lay.name,
171 adtb->lay.color);
172 }
173 adGetLayerState(dwghandle, adtb->lay.objhandle, &on, &frozen,
174 &vpfrozen, &locked);
175 if (on)
176 fprintf(stdout, "ON, ");
177 else
178 fprintf(stdout, "OFF, ");
179 if (frozen)
180 fprintf(stdout, "FROZEN, ");
181 else
182 fprintf(stdout, "THAWED, ");
183 if (vpfrozen)
184 fprintf(stdout, "VPFROZEN, ");
185 else
186 fprintf(stdout, "VPTHAWED, ");
187 if (locked)
188 fprintf(stdout, "LOCKED\n");
189 else
190 fprintf(stdout, "UNLOCKED\n");
191 }
192 adCloseFile(dwghandle);
193 adCloseAd2();
194 exit(EXIT_SUCCESS);
195 }
196
197
198 /* open output vector */
199 if (Vect_open_new(&Map, out_opt->answer, z_flag->answer) < 0)
200 G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
201
202 Vect_hist_command(&Map);
203
204 /* Add DB link */
205 Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
206 Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
207 Fi->driver);
208
209 driver =
210 db_start_driver_open_database(Fi->driver,
211 Vect_subst_var(Fi->database, &Map));
212 if (driver == NULL) {
213 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
214 Vect_subst_var(Fi->database, &Map), Fi->driver);
215 }
216 db_set_error_handler_driver(driver);
217
218 db_begin_transaction(driver);
219
220 /* Create table */
221 if (int_flag->answer) { /* List layers */
222 sprintf(buf,
223 "create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
224 "layer real, block varchar(100), txt varchar(100) )",
225 Fi->table);
226
227 }
228 else {
229 sprintf(buf,
230 "create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
231 "layer varchar(100), block varchar(100), txt varchar(100) )",
232 Fi->table);
233 }
234 db_set_string(&sql, buf);
235 G_debug(3, db_get_string(&sql));
236
237 if (db_execute_immediate(driver, &sql) != DB_OK) {
238 db_close_database(driver);
239 db_shutdown_driver(driver);
240 G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
241 }
242
243 if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
244 G_warning(_("Unable to create index for table <%s>, key <%s>"),
245 Fi->table, GV_KEY_COLUMN);
246
247 if (db_grant_on_table
248 (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
249 G_fatal_error(_("Unable to grant privileges on table <%s>"),
250 Fi->table);
251
252 cat = 1;
253 n_elements = n_skipped = 0;
254 /* Write each entity. Some entities may be composed by other entities (like INSERT or BLOCK) */
255 /* Set transformation for first (index 0) level */
256 Trans[0].dx = Trans[0].dy = Trans[0].dz = 0;
257 Trans[0].xscale = Trans[0].yscale = Trans[0].zscale = 1;
258 Trans[0].rotang = 0;
259 if (adGetBlockHandle(dwghandle, pspace, AD_PAPERSPACE_HANDLE)) {
260 entlist = adEntityList(dwghandle, pspace);
261 adStartEntityGet(entlist);
262 for (entset = 0; entset < 2; entset++) {
263 do {
264 if (!(retval = adGetEntity(entlist, adenhd, aden)))
265 continue;
266 wrentity(adenhd, aden, 0, entlist, circle_flag->answer);
267 } while (retval == 1);
268 if (entset == 0) {
269 if (adGetBlockHandle(dwghandle, mspace, AD_MODELSPACE_HANDLE)) {
270 entlist = adEntityList(dwghandle, mspace);
271 adStartEntityGet(entlist);
272 }
273 }
274 }
275 }
276
277 db_commit_transaction(driver);
278 db_close_database_shutdown_driver(driver);
279
280 adCloseFile(dwghandle);
281 adCloseAd2();
282
283 Vect_build(&Map, stderr);
284 Vect_close(&Map);
285
286 if (n_skipped > 0)
287 G_message(_("%d elements skipped (layer name was not in list)"),
288 n_skipped);
289
290 G_done_msg(_("%d elements processed"), n_elements);
291
292 exit(EXIT_SUCCESS);
293 }
294