1 /*
2
3 dxf_writer.c -- implements DXF support
4 [exporting a DXF]
5
6 version 5.0, 2020 August 1
7
8 Author: Sandro Furieri a.furieri@lqt.it
9
10 -----------------------------------------------------------------------------
11
12 Version: MPL 1.1/GPL 2.0/LGPL 2.1
13
14 The contents of this file are subject to the Mozilla Public License Version
15 1.1 (the "License"); you may not use this file except in compliance with
16 the License. You may obtain a copy of the License at
17 http://www.mozilla.org/MPL/
18
19 Software distributed under the License is distributed on an "AS IS" basis,
20 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
21 for the specific language governing rights and limitations under the
22 License.
23
24 The Original Code is the SpatiaLite library
25
26 The Initial Developer of the Original Code is Alessandro Furieri
27
28 Portions created by the Initial Developer are Copyright (C) 2008-2021
29 the Initial Developer. All Rights Reserved.
30
31 Contributor(s):
32
33 Alternatively, the contents of this file may be used under the terms of
34 either the GNU General Public License Version 2 or later (the "GPL"), or
35 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
36 in which case the provisions of the GPL or the LGPL are applicable instead
37 of those above. If you wish to allow use of your version of this file only
38 under the terms of either the GPL or the LGPL, and not to allow others to
39 use your version of this file under the terms of the MPL, indicate your
40 decision by deleting the provisions above and replace them with the notice
41 and other provisions required by the GPL or the LGPL. If you do not delete
42 the provisions above, a recipient may use your version of this file under
43 the terms of any one of the MPL, the GPL or the LGPL.
44
45 */
46
47 /*
48
49 CREDITS:
50
51 inital development of the DXF module has been funded by:
52 Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
53
54 */
55
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59
60 #if defined(_WIN32) && !defined(__MINGW32__)
61 #include "config-msvc.h"
62 #else
63 #include "config.h"
64 #endif
65
66 #include <spatialite/sqlite.h>
67 #include <spatialite/debug.h>
68
69 #include <spatialite/gaiageo.h>
70 #include <spatialite/gaiaaux.h>
71 #include <spatialite/gg_dxf.h>
72 #include <spatialite.h>
73 #include <spatialite_private.h>
74
75 #include "dxf_private.h"
76
77 #if defined(_WIN32) && !defined(__MINGW32__)
78 #define strcasecmp _stricmp
79 #endif /* not WIN32 */
80
81 GAIAGEO_DECLARE int
gaiaDxfWriterInit(gaiaDxfWriterPtr dxf,FILE * out,int precision,int version)82 gaiaDxfWriterInit (gaiaDxfWriterPtr dxf, FILE * out, int precision, int version)
83 {
84 /* initializing a DXF Output object */
85 if (dxf == NULL)
86 return 0;
87 dxf->error = 0;
88 dxf->precision = precision;
89 if (precision < 0)
90 dxf->precision = 0;
91 if (precision > 10)
92 dxf->precision = 10;
93 if (version != GAIA_DXF_V12)
94 dxf->error = 1;
95 else
96 dxf->version = GAIA_DXF_V12;
97 if (out == NULL)
98 dxf->error = 1;
99 else
100 dxf->out = out;
101 dxf->count = 0;
102 return 1;
103 }
104
105 GAIAGEO_DECLARE int
gaiaDxfWriteHeader(gaiaDxfWriterPtr dxf,double minx,double miny,double minz,double maxx,double maxy,double maxz)106 gaiaDxfWriteHeader (gaiaDxfWriterPtr dxf, double minx, double miny, double minz,
107 double maxx, double maxy, double maxz)
108 {
109 /* printing the DXF HEADER */
110 char format[128];
111 if (dxf == NULL)
112 return 0;
113 if (dxf->error)
114 return 0;
115 if (dxf->out == NULL)
116 return 0;
117
118 fprintf (dxf->out, "%3d\r\nSECTION\r\n%3d\r\nHEADER\r\n", 0, 2);
119 fprintf (dxf->out, "%3d\r\n$EXTMIN\r\n", 9);
120 sprintf (format,
121 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
122 dxf->precision, dxf->precision, dxf->precision);
123 fprintf (dxf->out, format, 10, minx, 20, miny, 30, minz);
124 fprintf (dxf->out, "%3d\r\n$EXTMAX\r\n", 9);
125 sprintf (format,
126 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
127 dxf->precision, dxf->precision, dxf->precision);
128 fprintf (dxf->out, format, 10, maxx, 20, maxy, 30, maxz);
129 fprintf (dxf->out, "%3d\r\nENDSEC\r\n", 0);
130 return 1;
131 }
132
133 GAIAGEO_DECLARE int
gaiaDxfWriteTables(gaiaDxfWriterPtr dxf)134 gaiaDxfWriteTables (gaiaDxfWriterPtr dxf)
135 {
136 /* printing the DXF TABLES section header */
137 if (dxf == NULL)
138 return 0;
139 if (dxf->error)
140 return 0;
141 if (dxf->out == NULL)
142 return 0;
143 fprintf (dxf->out, "%3d\r\nSECTION\r\n%3d\r\nTABLES\r\n", 0, 2);
144 return 1;
145 }
146
147 GAIAGEO_DECLARE int
gaiaDxfWriteLayer(gaiaDxfWriterPtr dxf,const char * layer)148 gaiaDxfWriteLayer (gaiaDxfWriterPtr dxf, const char *layer)
149 {
150 /* printing a DXF TABLE/LAYER definition */
151 if (dxf == NULL)
152 return 0;
153 if (dxf->error)
154 return 0;
155 if (dxf->out == NULL)
156 return 0;
157 fprintf (dxf->out, "%3d\r\nTABLE\r\n%3d\r\nLAYER\r\n", 0, 2);
158 fprintf (dxf->out, "%3d\r\n%3d\r\n%3d\r\nLAYER\r\n%3d\r\n%s\r\n", 70, 1, 0,
159 2, layer);
160 fprintf (dxf->out, "%3d\r\n%d\r\n%3d\r\n%d\r\n%3d\r\nCONTINUOUS\r\n", 70,
161 64, 62, 7, 6);
162 fprintf (dxf->out, "%3d\r\nENDTAB\r\n", 0);
163 return 1;
164 }
165
166 GAIAGEO_DECLARE int
gaiaDxfWriteFooter(gaiaDxfWriterPtr dxf)167 gaiaDxfWriteFooter (gaiaDxfWriterPtr dxf)
168 {
169 /* printing the DXF footer */
170 if (dxf == NULL)
171 return 0;
172 if (dxf->error)
173 return 0;
174 if (dxf->out == NULL)
175 return 0;
176 fprintf (dxf->out, "%3d\r\nEOF\r\n", 0);
177 return 1;
178 }
179
180 GAIAGEO_DECLARE int
gaiaDxfWriteEntities(gaiaDxfWriterPtr dxf)181 gaiaDxfWriteEntities (gaiaDxfWriterPtr dxf)
182 {
183 /* printing the DXF ENTITIES section header */
184 if (dxf == NULL)
185 return 0;
186 if (dxf->error)
187 return 0;
188 if (dxf->out == NULL)
189 return 0;
190 fprintf (dxf->out, "%3d\r\nSECTION\r\n%3d\r\nENTITIES\r\n", 0, 2);
191 return 1;
192 }
193
194 GAIAGEO_DECLARE int
gaiaDxfWriteEndSection(gaiaDxfWriterPtr dxf)195 gaiaDxfWriteEndSection (gaiaDxfWriterPtr dxf)
196 {
197 /* printing a DXF ENDSEC */
198 if (dxf == NULL)
199 return 0;
200 if (dxf->error)
201 return 0;
202 if (dxf->out == NULL)
203 return 0;
204 fprintf (dxf->out, "%3d\r\nENDSEC\r\n", 0);
205 return 1;
206 }
207
208 GAIAGEO_DECLARE int
gaiaDxfWritePoint(gaiaDxfWriterPtr dxf,const char * layer,double x,double y,double z)209 gaiaDxfWritePoint (gaiaDxfWriterPtr dxf, const char *layer, double x, double y,
210 double z)
211 {
212 /* printing a DXF POINT */
213 char format[128];
214 if (dxf == NULL)
215 return 0;
216 if (dxf->error)
217 return 0;
218 if (dxf->out == NULL)
219 return 0;
220 fprintf (dxf->out, "%3d\r\nPOINT\r\n%3d\r\n%s\r\n", 0, 8, layer);
221 sprintf (format,
222 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
223 dxf->precision, dxf->precision, dxf->precision);
224 fprintf (dxf->out, format, 10, x, 20, y, 30, z);
225 dxf->count++;
226 return 1;
227 }
228
229 GAIAGEO_DECLARE int
gaiaDxfWriteText(gaiaDxfWriterPtr dxf,const char * layer,double x,double y,double z,const char * label,double text_height,double angle)230 gaiaDxfWriteText (gaiaDxfWriterPtr dxf, const char *layer, double x, double y,
231 double z, const char *label, double text_height, double angle)
232 {
233 /* printing a DXF TEXT */
234 char format[128];
235 if (dxf == NULL)
236 return 0;
237 if (dxf->error)
238 return 0;
239 if (dxf->out == NULL)
240 return 0;
241 fprintf (dxf->out, "%3d\r\nTEXT\r\n%3d\r\n%s\r\n", 0, 8, layer);
242 sprintf (format,
243 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
244 dxf->precision, dxf->precision, dxf->precision);
245 fprintf (dxf->out, format, 10, x, 20, y, 30, z);
246 sprintf (format, "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%s\r\n",
247 dxf->precision, dxf->precision);
248 fprintf (dxf->out, format, 40, text_height, 50, angle, 1, label);
249 dxf->count++;
250 return 1;
251 }
252
253 GAIAGEO_DECLARE int
gaiaDxfWriteLine(gaiaDxfWriterPtr dxf,const char * layer,gaiaLinestringPtr line)254 gaiaDxfWriteLine (gaiaDxfWriterPtr dxf, const char *layer,
255 gaiaLinestringPtr line)
256 {
257 /* printing a DXF POLYLINE (opened) */
258 int iv;
259 double x;
260 double y;
261 double z;
262 double m;
263 char format[128];
264 if (dxf == NULL)
265 return 0;
266 if (dxf->error)
267 return 0;
268 if (dxf->out == NULL)
269 return 0;
270 fprintf (dxf->out, "%3d\r\nPOLYLINE\r\n%3d\r\n%s\r\n%3d\r\n%6d\r\n", 0, 8,
271 layer, 66, 1);
272 fprintf (dxf->out, "%3d\r\n%6d\r\n", 70, 0);
273 for (iv = 0; iv < line->Points; iv++)
274 {
275 /* exporting all vertices */
276 m = 0.0;
277 z = 0.0;
278 if (line->DimensionModel == GAIA_XY_Z)
279 {
280 gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
281 }
282 else if (line->DimensionModel == GAIA_XY_M)
283 {
284 gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
285 }
286 else if (line->DimensionModel == GAIA_XY_Z_M)
287 {
288 gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
289 }
290 else
291 {
292 gaiaGetPoint (line->Coords, iv, &x, &y);
293 }
294 fprintf (dxf->out, "%3d\r\nVERTEX\r\n%3d\r\n%s\r\n", 0, 8, layer);
295 sprintf (format,
296 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
297 dxf->precision, dxf->precision, dxf->precision);
298 fprintf (dxf->out, format, 10, x, 20, y, 30, z);
299 }
300 fprintf (dxf->out, "%3d\r\nSEQEND\r\n%3d\r\n%s\r\n", 0, 8, layer);
301 dxf->count++;
302 return 1;
303 }
304
305 GAIAGEO_DECLARE int
gaiaDxfWriteRing(gaiaDxfWriterPtr dxf,const char * layer,gaiaRingPtr ring)306 gaiaDxfWriteRing (gaiaDxfWriterPtr dxf, const char *layer, gaiaRingPtr ring)
307 {
308 /* printing a DXF POLYLINE (closed) */
309 int iv;
310 double x;
311 double y;
312 double z;
313 double m;
314 char format[128];
315 if (dxf == NULL)
316 return 0;
317 if (dxf->error)
318 return 0;
319 if (dxf->out == NULL)
320 return 0;
321 fprintf (dxf->out, "%3d\r\nPOLYLINE\r\n%3d\r\n%s\r\n%3d\r\n%6d\r\n", 0, 8,
322 layer, 66, 1);
323 fprintf (dxf->out, "%3d\r\n%6d\r\n", 70, 1);
324 for (iv = 0; iv < ring->Points - 1; iv++)
325 {
326 /* sandro 2013-10-19
327 exporting all vertices except the last one
328 because accordingly to DXF specifications the
329 Ring closure is always implicitly assumed, so
330 there is no need at all to explicitly export
331 a last vertex identical to the first one */
332 m = 0.0;
333 z = 0.0;
334 if (ring->DimensionModel == GAIA_XY_Z)
335 {
336 gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
337 }
338 else if (ring->DimensionModel == GAIA_XY_M)
339 {
340 gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
341 }
342 else if (ring->DimensionModel == GAIA_XY_Z_M)
343 {
344 gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
345 }
346 else
347 {
348 gaiaGetPoint (ring->Coords, iv, &x, &y);
349 }
350 fprintf (dxf->out, "%3d\r\nVERTEX\r\n%3d\r\n%s\r\n", 0, 8, layer);
351 sprintf (format,
352 "%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n%%3d\r\n%%1.%df\r\n",
353 dxf->precision, dxf->precision, dxf->precision);
354 fprintf (dxf->out, format, 10, x, 20, y, 30, z);
355 }
356 fprintf (dxf->out, "%3d\r\nSEQEND\r\n%3d\r\n%s\r\n", 0, 8, layer);
357 dxf->count++;
358 return 1;
359 }
360
361 GAIAGEO_DECLARE int
gaiaDxfWriteGeometry(gaiaDxfWriterPtr dxf,const char * layer,const char * label,double text_height,double text_rotation,gaiaGeomCollPtr geom)362 gaiaDxfWriteGeometry (gaiaDxfWriterPtr dxf, const char *layer,
363 const char *label, double text_height,
364 double text_rotation, gaiaGeomCollPtr geom)
365 {
366 /* exporting a whole Geometry into the DXF */
367 gaiaPointPtr pt;
368 gaiaLinestringPtr ln;
369 gaiaPolygonPtr pg;
370 gaiaRingPtr rng;
371 int ib;
372 if (dxf == NULL)
373 return 0;
374 if (dxf->error)
375 return 0;
376 if (dxf->out == NULL)
377 return 0;
378 pt = geom->FirstPoint;
379 while (pt != NULL)
380 {
381 if (label == NULL)
382 gaiaDxfWritePoint (dxf, layer, pt->X, pt->Y, pt->Z);
383 else
384 gaiaDxfWriteText (dxf, layer, pt->X, pt->Y, pt->Z, label,
385 text_height, text_rotation);
386 pt = pt->Next;
387 }
388 ln = geom->FirstLinestring;
389 while (ln != NULL)
390 {
391 gaiaDxfWriteLine (dxf, layer, ln);
392 ln = ln->Next;
393 }
394 pg = geom->FirstPolygon;
395 while (pg != NULL)
396 {
397 rng = pg->Exterior;
398 gaiaDxfWriteRing (dxf, layer, rng);
399 for (ib = 0; ib < pg->NumInteriors; ib++)
400 {
401 rng = pg->Interiors + ib;
402 gaiaDxfWriteRing (dxf, layer, rng);
403 }
404 pg = pg->Next;
405 }
406 return 1;
407 }
408
409 static gaiaDxfExportLayerPtr
alloc_aux_layer(const char * layer,gaiaGeomCollPtr geom)410 alloc_aux_layer (const char *layer, gaiaGeomCollPtr geom)
411 {
412 /* allocating and initializing an helper Layer */
413 int len;
414 gaiaDxfExportLayerPtr lyr = malloc (sizeof (gaiaDxfExportLayer));
415 len = strlen (layer);
416 lyr->layer_name = malloc (len + 1);
417 strcpy (lyr->layer_name, layer), lyr->minx = geom->MinX;
418 lyr->miny = geom->MinY;
419 lyr->maxx = geom->MaxX;
420 lyr->maxy = geom->MaxY;
421 lyr->next = NULL;
422 return lyr;
423 }
424
425 static void
destroy_aux_layer(gaiaDxfExportLayerPtr lyr)426 destroy_aux_layer (gaiaDxfExportLayerPtr lyr)
427 {
428 /* destroying a DXF Helper Layer */
429 if (lyr == NULL)
430 return;
431 if (lyr->layer_name != NULL)
432 free (lyr->layer_name);
433 free (lyr);
434 }
435
436 static gaiaDxfExportPtr
alloc_aux_exporter()437 alloc_aux_exporter ()
438 {
439 /* allocating and initializing the helper Exporter */
440 gaiaDxfExportPtr aux = malloc (sizeof (gaiaDxfExport));
441 aux->first = NULL;
442 aux->last = NULL;
443 return aux;
444 }
445
446 static void
destroy_aux_exporter(gaiaDxfExportPtr aux)447 destroy_aux_exporter (gaiaDxfExportPtr aux)
448 {
449 /* memory cleanup - destroying the helper Exporter */
450 gaiaDxfExportLayerPtr lyr;
451 gaiaDxfExportLayerPtr n_lyr;
452 if (aux == NULL)
453 return;
454 lyr = aux->first;
455 while (lyr != NULL)
456 {
457 n_lyr = lyr->next;
458 destroy_aux_layer (lyr);
459 lyr = n_lyr;
460 }
461 free (aux);
462 }
463
464 static void
update_aux_exporter(gaiaDxfExportPtr aux,const char * layer,gaiaGeomCollPtr geom)465 update_aux_exporter (gaiaDxfExportPtr aux, const char *layer,
466 gaiaGeomCollPtr geom)
467 {
468 /* updating the Helper Exporter */
469 gaiaDxfExportLayerPtr lyr = aux->first;
470 while (lyr != NULL)
471 {
472 if (strcasecmp (layer, lyr->layer_name) == 0)
473 {
474 /* updating an already defined layer */
475 if (geom->MinX < lyr->minx)
476 lyr->minx = geom->MinX;
477 if (geom->MinY < lyr->miny)
478 lyr->miny = geom->MinY;
479 if (geom->MaxX > lyr->maxx)
480 lyr->maxx = geom->MaxX;
481 if (geom->MaxY > lyr->maxy)
482 lyr->maxy = geom->MaxY;
483 if (geom->MinX < aux->minx)
484 aux->minx = geom->MinX;
485 if (geom->MinY < aux->miny)
486 aux->miny = geom->MinY;
487 if (geom->MaxX > aux->maxx)
488 aux->maxx = geom->MaxX;
489 if (geom->MaxY > aux->maxy)
490 aux->maxy = geom->MaxY;
491 return;
492 }
493 lyr = lyr->next;
494 }
495 /* inserting a new Layer */
496 lyr = alloc_aux_layer (layer, geom);
497 if (aux->first == NULL)
498 {
499 aux->first = lyr;
500 aux->minx = geom->MinX;
501 aux->miny = geom->MinY;
502 aux->maxx = geom->MaxX;
503 aux->maxy = geom->MaxY;
504 }
505 if (aux->last != NULL)
506 aux->last->next = lyr;
507 aux->last = lyr;
508 }
509
510 GAIAGEO_DECLARE int
gaiaExportDxf(gaiaDxfWriterPtr dxf,sqlite3 * db_handle,const char * sql,const char * layer_col_name,const char * geom_col_name,const char * label_col_name,const char * text_height_col_name,const char * text_rotation_col_name,gaiaGeomCollPtr geom_filter)511 gaiaExportDxf (gaiaDxfWriterPtr dxf, sqlite3 * db_handle,
512 const char *sql, const char *layer_col_name,
513 const char *geom_col_name, const char *label_col_name,
514 const char *text_height_col_name,
515 const char *text_rotation_col_name, gaiaGeomCollPtr geom_filter)
516 {
517 /* exporting a complex DXF by executing an arbitrary SQL query */
518 sqlite3_stmt *stmt = NULL;
519 int ret;
520 int params;
521 int first_row = 1;
522 int layer_col = -1;
523 int geom_col = -1;
524 int label_col = -1;
525 int text_height_col = -1;
526 int text_rotation_col = -1;
527 int i;
528 unsigned char *p_blob;
529 const unsigned char *blob;
530 int len;
531 const char *layer;
532 const char *label = NULL;
533 gaiaGeomCollPtr geom;
534 gaiaDxfExportPtr aux = NULL;
535 gaiaDxfExportLayerPtr lyr;
536 if (dxf == NULL)
537 return 0;
538 if (dxf->error)
539 return 0;
540 if (dxf->out == NULL)
541 return 0;
542 if (db_handle == NULL)
543 return 0;
544 if (sql == NULL)
545 return 0;
546 if (layer_col_name == NULL)
547 return 0;
548 if (geom_col_name == NULL)
549 return 0;
550
551 /* attempting to create the SQL prepared statement */
552 ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
553 if (ret != SQLITE_OK)
554 {
555 spatialite_e ("exportDXF - CREATE STATEMENT error: %s\n",
556 sqlite3_errmsg (db_handle));
557 goto stop;
558 }
559 params = sqlite3_bind_parameter_count (stmt);
560
561 if (params > 0 && geom_filter != NULL)
562 {
563 /* parameter binding - Spatial Filter */
564 sqlite3_reset (stmt);
565 sqlite3_clear_bindings (stmt);
566 for (i = 1; i <= params; i++)
567 {
568 gaiaToSpatiaLiteBlobWkb (geom_filter, &p_blob, &len);
569 ret = sqlite3_bind_blob (stmt, i, p_blob, len, free);
570 if (ret != SQLITE_OK)
571 {
572 spatialite_e ("exportDXF - parameter BIND error: %s\n",
573 sqlite3_errmsg (db_handle));
574 goto stop;
575 }
576 }
577 }
578
579 /* pass #1 - sniffing the result set */
580 while (1)
581 {
582 /* scrolling the result set rows */
583 ret = sqlite3_step (stmt);
584 if (ret == SQLITE_DONE)
585 break; /* end of result set */
586 if (ret == SQLITE_ROW)
587 {
588 if (first_row)
589 {
590 /* this one is the first row of the resultset */
591 for (i = 0; i < sqlite3_column_count (stmt); i++)
592 {
593 /* attempting to identify the resultset columns */
594 if (strcasecmp
595 (layer_col_name,
596 sqlite3_column_name (stmt, i)) == 0)
597 layer_col = i;
598 if (strcasecmp
599 (geom_col_name,
600 sqlite3_column_name (stmt, i)) == 0)
601 geom_col = i;
602 if (label_col_name != NULL)
603 {
604 if (strcasecmp
605 (label_col_name,
606 sqlite3_column_name (stmt, i)) == 0)
607 label_col = i;
608 }
609 if (text_height_col_name != NULL)
610 {
611 if (strcasecmp
612 (text_height_col_name,
613 sqlite3_column_name (stmt, i)) == 0)
614 text_height_col = i;
615 }
616 if (text_rotation_col_name != NULL)
617 {
618 if (strcasecmp
619 (text_rotation_col_name,
620 sqlite3_column_name (stmt, i)) == 0)
621 text_rotation_col = i;
622 }
623 }
624 if (layer_col < 0)
625 {
626 spatialite_e
627 ("exportDXF - Layer Column not found into the resultset\n");
628 goto stop;
629 }
630 if (geom_col < 0)
631 {
632 spatialite_e
633 ("exportDXF - Geometry Column not found into the resultset\n");
634 goto stop;
635 }
636 first_row = 0;
637 aux = alloc_aux_exporter ();
638 }
639 layer = (const char *) sqlite3_column_text (stmt, layer_col);
640 blob = sqlite3_column_blob (stmt, geom_col);
641 len = sqlite3_column_bytes (stmt, geom_col);
642 geom = gaiaFromSpatiaLiteBlobWkb (blob, len);
643 if (geom)
644 {
645 update_aux_exporter (aux, layer, geom);
646 gaiaFreeGeomColl (geom);
647 }
648 }
649 }
650
651 /* pass #2 - exporting the DXF file */
652 gaiaDxfWriteHeader (dxf, aux->minx, aux->miny, 0, aux->maxx, aux->maxy, 0);
653 gaiaDxfWriteTables (dxf);
654 lyr = aux->first;
655 while (lyr != NULL)
656 {
657 gaiaDxfWriteLayer (dxf, lyr->layer_name);
658 lyr = lyr->next;
659 }
660 gaiaDxfWriteEndSection (dxf);
661 gaiaDxfWriteEntities (dxf);
662
663 sqlite3_reset (stmt);
664 while (1)
665 {
666 /* scrolling the result set rows */
667 int ival;
668 double height = 10.0;
669 double rotation = 0.0;
670 ret = sqlite3_step (stmt);
671 if (ret == SQLITE_DONE)
672 break; /* end of result set */
673 if (ret == SQLITE_ROW)
674 {
675 layer = (const char *) sqlite3_column_text (stmt, layer_col);
676 if (label_col >= 0)
677 label =
678 (const char *) sqlite3_column_text (stmt, label_col);
679 if (text_height_col >= 0)
680 {
681 if (sqlite3_column_type (stmt, text_height_col) ==
682 SQLITE_INTEGER)
683 {
684 ival = sqlite3_column_int (stmt, text_height_col);
685 height = ival;
686 }
687 if (sqlite3_column_type (stmt, text_height_col) ==
688 SQLITE_FLOAT)
689 height =
690 sqlite3_column_double (stmt, text_height_col);
691 }
692 if (text_rotation_col >= 0)
693 {
694 if (sqlite3_column_type (stmt, text_rotation_col) ==
695 SQLITE_INTEGER)
696 {
697 ival = sqlite3_column_int (stmt, text_rotation_col);
698 rotation = ival;
699 }
700 if (sqlite3_column_type (stmt, text_height_col) ==
701 SQLITE_FLOAT)
702 rotation =
703 sqlite3_column_double (stmt, text_rotation_col);
704 }
705 blob = sqlite3_column_blob (stmt, geom_col);
706 len = sqlite3_column_bytes (stmt, geom_col);
707 geom = gaiaFromSpatiaLiteBlobWkb (blob, len);
708 if (geom)
709 {
710 gaiaDxfWriteGeometry (dxf, layer, label, height, rotation,
711 geom);
712 gaiaFreeGeomColl (geom);
713 }
714 }
715 }
716 gaiaDxfWriteEndSection (dxf);
717 gaiaDxfWriteFooter (dxf);
718
719 sqlite3_finalize (stmt);
720 if (aux != NULL)
721 destroy_aux_exporter (aux);
722 return dxf->count;
723
724 stop:
725 if (stmt != NULL)
726 sqlite3_finalize (stmt);
727 if (aux != NULL)
728 destroy_aux_exporter (aux);
729 return 0;
730 }
731