[GRASS-SVN] r43170 - in grass-addons/vector: . v.in.redwg

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Aug 20 18:32:09 EDT 2010


Author: pitanga
Date: 2010-08-20 22:32:09 +0000 (Fri, 20 Aug 2010)
New Revision: 43170

Added:
   grass-addons/vector/v.in.redwg/
   grass-addons/vector/v.in.redwg/Makefile
   grass-addons/vector/v.in.redwg/README
   grass-addons/vector/v.in.redwg/entity.c
   grass-addons/vector/v.in.redwg/global.h
   grass-addons/vector/v.in.redwg/main.c
   grass-addons/vector/v.in.redwg/v.in.redwg.html
Log:
Initial commit of v.in.redwg - DWG import with no need of proprietary library (could be shipped with GRASS in the future)

Added: grass-addons/vector/v.in.redwg/Makefile
===================================================================
--- grass-addons/vector/v.in.redwg/Makefile	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/Makefile	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,20 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.in.redwg
+
+## hard coded
+LIBREDWGLIB=-lredwg
+#LIBREDWGLIBPATH=/usr/local/lib
+#LIBREDWGINCPATH=/usr/local/include/dwg.h
+
+DEPENDENCIES = $(VECTDEP) $(DBMIDEP) $(GISDEP)
+LIBES     = $(VECTLIB) $(DBMILIB) $(GISLIB) $(LIBREDWGLIBPATH) $(LIBREDWGLIB)
+EXTRA_INC = $(VECT_INC) $(LIBREDWGINCPATH)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+#ifneq ($(USE_LIBREDWG),)
+default: cmd
+#endif
+

Added: grass-addons/vector/v.in.redwg/README
===================================================================
--- grass-addons/vector/v.in.redwg/README	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/README	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,12 @@
+v.in.redwg requires GNU LibreDWG. To get this library go to 
+http://gnu.org/s/libredwg (no official release yet, you need to check out the
+source code and compile).
+
+Warning: some trick might be needed to build it since I created the Makefile 
+while attached to the main grass tree (svn trunk). I did not try to build it 
+after committing to the GRASS-Addons-svn, but I will try to fix it and clean up
+the code soon.
+
+Not to mention that this is still in alpha stage, as LibreDWG, although I
+managed to get some concrete results. Not all entity types are supported 
+(warning printed).

Added: grass-addons/vector/v.in.redwg/entity.c
===================================================================
--- grass-addons/vector/v.in.redwg/entity.c	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/entity.c	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,534 @@
+/* **************************************************************
+ * 
+ *  MODULE:       v.in.redwg
+ *  
+ *  AUTHOR(S):    Rodrigo Rodrigues da Silva
+ *                based on original code by Radim Blazek
+ *                
+ *  PURPOSE:      Import of DWG files (using free software lib)
+ *                
+ *  COPYRIGHT:    (C) 2001, 2010 by the GRASS Development Team
+ * 
+ *                This program is free software under the 
+ *                GNU General Public License (>=v2). 
+ *                Read the file COPYING that comes with GRASS
+ *                for details.
+ * 
+ * **************************************************************/
+
+/*
+ * Unsupported entities must be added in write_entity()
+ *
+ * TODO: 3rd dimension is not functional for CIRCLE and ARC
+ *       -> required updated of transformation in INSERT
+ *          (how to do that??)
+ */
+
+#define AD_PROTOTYPES
+#define AD_VM_PC
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/vector.h>
+#include <dwg.h>
+#include "global.h"
+
+#define exampleprintf printf
+#define LOCPI M_PI
+
+char buf[1000];
+char buf2[1000];
+
+void getEntTypeName(Dwg_Object *obj, char *name)
+{
+    switch (obj->type)
+    {
+    case DWG_TYPE_LINE:
+	strcpy(name, "LINE");
+	break;
+    case DWG_TYPE_POINT:
+	strcpy(name, "POINT");
+	break;
+    case DWG_TYPE_CIRCLE:
+	strcpy(name, "CIRCLE");
+	break;
+    case DWG_TYPE_SHAPE:
+	strcpy(name, "SHAPE");
+	break;
+    case DWG_TYPE_ELLIPSE:
+	strcpy(name, "ELLIPSE");
+	break;
+    case DWG_TYPE_SPLINE:
+	strcpy(name, "SPLINE");
+	break;
+    case DWG_TYPE_TEXT:
+	strcpy(name, "TEXT");
+	break;
+    case DWG_TYPE_ARC:
+	strcpy(name, "ARC");
+	break;
+    case DWG_TYPE_TRACE:
+	strcpy(name, "TRACE");
+	break;
+    case DWG_TYPE_SOLID:
+	strcpy(name, "SOLID");
+	break;
+    case DWG_TYPE_BLOCK:
+	strcpy(name, "BLOCK");
+	break;
+    case DWG_TYPE_ENDBLK:
+	strcpy(name, "ENDBLK");
+	break;
+    case DWG_TYPE_INSERT:
+	strcpy(name, "INSERT");
+	break;
+    case DWG_TYPE_ATTDEF:
+	strcpy(name, "ATTDEF");
+	break;
+    case DWG_TYPE_ATTRIB:
+	strcpy(name, "ATTRIB");
+	break;
+    case DWG_TYPE_SEQEND:
+	strcpy(name, "SEQEND");
+	break;
+    case DWG_TYPE_POLYLINE_2D:
+    case DWG_TYPE_POLYLINE_3D:
+	strcpy(name, "POLYLINE");
+	break;
+    case  DWG_TYPE_VERTEX_2D:
+    case  DWG_TYPE_VERTEX_3D:
+    case  DWG_TYPE_VERTEX_MESH:
+    case  DWG_TYPE_VERTEX_PFACE:
+    case  DWG_TYPE_VERTEX_PFACE_FACE:
+	strcpy(name, "VERTEX");
+	break;
+	/*
+    case AD_ENT_LINE3D:
+	strcpy(name, "3DLINE");
+	break;
+    case AD_ENT_FACE3D:
+	strcpy(name, "3DFACE");
+	break;
+	*/
+
+    case  DWG_TYPE_DIMENSION_ORDINATE:
+    case  DWG_TYPE_DIMENSION_LINEAR:
+    case  DWG_TYPE_DIMENSION_ALIGNED:
+    case  DWG_TYPE_DIMENSION_ANG3PT:
+    case  DWG_TYPE_DIMENSION_ANG2LN:
+    case  DWG_TYPE_DIMENSION_RADIUS:
+    case  DWG_TYPE_DIMENSION_DIAMETER:
+	strcpy(name, "DIMENSION");
+	break;
+    case DWG_TYPE_VIEWPORT:
+	strcpy(name, "VIEWPORT");
+	break;
+    case DWG_TYPE_3DSOLID:
+	strcpy(name, "SOLID3D");
+	break;
+    case DWG_TYPE_RAY:
+	strcpy(name, "RAY");
+	break;
+    case DWG_TYPE_XLINE:
+	strcpy(name, "XLINE");
+	break;
+    case DWG_TYPE_MTEXT:
+	strcpy(name, "MTEXT");
+	break;
+    case DWG_TYPE_LEADER:
+	strcpy(name, "LEADER");
+	break;
+    case DWG_TYPE_TOLERANCE:
+	strcpy(name, "TOLERANCE");
+	break;
+    case DWG_TYPE_MLINE:
+	strcpy(name, "MLINE");
+	break;
+    case DWG_TYPE_BODY:
+	strcpy(name, "BODY");
+	break;
+    case DWG_TYPE_REGION:
+	strcpy(name, "REGION");
+	break;
+    default:
+       strcpy(name, "UNKNOWN");
+       /*
+	if (adenhd->enttype == adOle2frameEnttype(dwghandle))
+	    strcpy(name, "OLE2FRAME");
+	else if (adenhd->enttype == adLwplineEnttype(dwghandle))
+	    strcpy(name, "LWPOLYLINE");
+	else if (adenhd->enttype == adHatchEnttype(dwghandle))
+	    strcpy(name, "HATCH");
+	else if (adenhd->enttype == adImageEnttype(dwghandle))
+	    strcpy(name, "IMAGE");
+	else if (adenhd->enttype == adArcAlignedTextEnttype(dwghandle))
+	    strcpy(name, "ArcAlignedText");
+	else if (adenhd->enttype == adWipeoutEnttype(dwghandle))
+	    strcpy(name, "Wipeout");
+	else if (adenhd->enttype == adRtextEnttype(dwghandle))
+	    strcpy(name, "Rtext");
+	else {
+
+	    G_debug(3, "adenhd->enttype: %d", adenhd->enttype);
+	    strcpy(name, "Proxy");
+	}
+	*/
+	break;
+    }
+}
+
+int write_line(Dwg_Object * obj, int type, int level)
+{
+    int i, l;
+    double x, y, z, r, ang;
+
+    /*
+    adSeekLayer(dwghandle, obj->entlayerobjhandle, Layer);
+    */
+
+    /* Transformation, go up through all levels of transformation */
+    /* not sure what is the right order of transformation */
+    for (l = level; l >= 0; l--) {
+	for (i = 0; i < Points->n_points; i++) {
+	    /* scale */
+	    x = Points->x[i] * Trans[l].xscale;
+	    y = Points->y[i] * Trans[l].yscale;
+	    z = Points->z[i] * Trans[l].zscale;
+	    /* rotate */
+	    r = sqrt(x * x + y * y);
+	    ang = atan2(y, x) + Trans[l].rotang;
+	    x = r * cos(ang);
+	    y = r * sin(ang);
+	    /* move */
+	    x += Trans[l].dx;
+	    y += Trans[l].dy;
+	    z += Trans[l].dz;
+	    Points->x[i] = x;
+	    Points->y[i] = y;
+	    Points->z[i] = z;
+	}
+    }
+
+    Vect_reset_cats(Cats);
+    Vect_cat_set(Cats, 1, cat);
+    Vect_write_line(&Map, type, Points, Cats);
+
+    /* Cat */
+    sprintf(buf, "insert into %s values ( %d", Fi->table, cat);
+    db_set_string(&sql, buf);
+
+    /* Entity name */
+    getEntTypeName(obj, buf2);
+    sprintf(buf, ", '%s'", buf2);
+    db_append_string(&sql, buf);
+
+    /* Color */
+    sprintf(buf, ", %lu", obj->tio.entity->color.rgb);
+    db_append_string(&sql, buf);
+
+    /* Weight */
+    sprintf(buf, ", %d", obj->tio.entity->lineweight);
+    db_append_string(&sql, buf);
+
+    /* Layer name */
+
+    /*!Layer->purgedflag && */
+
+    printf("This should be a layer: " );
+    Dwg_Object * should_be_layer = obj->tio.entity->layer->obj;
+    Dwg_Object_LAYER * layer;
+    unsigned int _type = should_be_layer->type;
+    //dwg_print_object(should_be_layer);
+    printf("type = %u ", _type);
+    if (_type == 51)
+      {
+        layer = obj->tio.entity->layer->obj->tio.object->tio.LAYER;
+        printf ("IS A LAYER! name = %s", layer->entry_name);
+      }
+    else printf("NOT A LAYER!");
+    printf("\n");
+
+    if (layer) {
+      if (layer->entry_name) {
+	db_set_string(&str, layer->entry_name);
+	db_double_quote_string(&str);
+	sprintf(buf, ", '%s'", db_get_string(&str));
+      }
+    }
+    else {
+	sprintf(buf, ", ''");
+    }
+    db_append_string(&sql, buf);
+
+    /* Block name */
+    if (Block != NULL) {
+	db_set_string(&str, Block);
+	db_double_quote_string(&str);
+    }
+    else {
+	db_set_string(&str, "");
+    }
+    sprintf(buf, ", '%s'", db_get_string(&str));
+    db_append_string(&sql, buf);
+
+    /* Text */
+    if (Txt != NULL) {
+	db_set_string(&str, Txt);
+	db_double_quote_string(&str);
+    }
+    else {
+	db_set_string(&str, "");
+    }
+    sprintf(buf, ", '%s'", db_get_string(&str));
+    db_append_string(&sql, buf);
+
+    db_append_string(&sql, ")");
+    G_debug(3, db_get_string(&sql));
+
+    if (db_execute_immediate(driver, &sql) != DB_OK) {
+	db_close_database(driver);
+	db_shutdown_driver(driver);
+	G_fatal_error("Cannot insert new row: %s", db_get_string(&sql));
+    }
+
+    cat++;
+    return 0;
+}
+
+/* Returns 1 if element has geometry and may be written to vector */
+int is_low_level(Dwg_Object *obj)
+{
+    if (obj->type == DWG_TYPE_BLOCK || obj->type == DWG_TYPE_ENDBLK ||
+        obj->type == DWG_TYPE_SEQEND || obj->type == DWG_TYPE_INSERT)
+    {
+	return 0;
+    }
+    return 1;
+}
+
+void write_entity(Dwg_Object *obj, Dwg_Object ** objects,
+      long unsigned int *ent_counter, int level)
+{
+    double x, y, z, ang;
+    int i;
+
+    /* DWG entity pointers */
+    Dwg_Entity_LINE *line;
+    Dwg_Entity__3DFACE *face3d;
+    Dwg_Entity_SOLID *solid;
+    Dwg_Entity_TEXT *text;
+    Dwg_Entity_POINT *point;
+    Dwg_Entity_ARC *arc;
+    Dwg_Entity_CIRCLE *circle;
+    Dwg_Entity_BLOCK *block;
+    Dwg_Entity_INSERT *insert;
+    Dwg_Object *_obj;
+    Dwg_Object_Object *_obj_obj;
+    Dwg_Object_BLOCK_HEADER *blockhdr;
+
+
+    *ent_counter += 1;
+    if (is_low_level(obj))
+	n_elements++;
+
+
+    getEntTypeName(obj, buf);
+    G_debug(1, "Entity: %s", buf);
+    fprintf(stdout, "Entity: %s %u\n", buf, obj->type);
+
+    Txt = NULL;
+    Vect_reset_line(Points);
+
+    /* Check space for lower level */
+    if (level + 1 == atrans) {
+	atrans += 10;
+	Trans = (TRANS *) G_realloc(Trans, atrans * sizeof(TRANS));
+    }
+
+    switch (obj->type) {
+    case DWG_TYPE_LINE:
+        line = obj->tio.entity->tio.LINE;
+	Vect_append_point(Points, line->start.x, line->start.y,
+	    line->start.z);
+	Vect_append_point(Points, line->end.x, line->end.y,
+	            line->end.z);
+	write_line(obj, GV_LINE, level);
+	break;
+
+    case DWG_TYPE__3DFACE:
+        face3d = obj->tio.entity->tio._3DFACE;
+	Vect_append_point(Points, face3d->corner1.x, face3d->corner1.y,
+	    face3d->corner1.z);
+        Vect_append_point(Points, face3d->corner2.x, face3d->corner2.y,
+            face3d->corner2.z);
+        Vect_append_point(Points, face3d->corner3.x, face3d->corner3.y,
+            face3d->corner3.z);
+        Vect_append_point(Points, face3d->corner4.x, face3d->corner4.y,
+            face3d->corner4.z);
+	write_line(obj, GV_FACE, level);
+	break;
+
+    case DWG_TYPE_SOLID:
+        solid = obj->tio.entity->tio.SOLID;
+        Vect_append_point(Points, solid->corner1.x, solid->corner1.y,
+            solid->elevation);
+        Vect_append_point(Points, solid->corner2.x, solid->corner2.y,
+            solid->elevation);
+        Vect_append_point(Points, solid->corner3.x, solid->corner3.y,
+            solid->elevation);
+        Vect_append_point(Points, solid->corner4.x, solid->corner4.y,
+            solid->elevation);
+	write_line(obj, GV_FACE, level);
+	break;
+
+    case DWG_TYPE_TEXT:
+        text = obj->tio.entity->tio.TEXT;
+	Txt = (char *)text->text_value;
+	Vect_append_point(Points, text->insertion_pt.x, text->insertion_pt.y,
+			  0); // insertion_poin.z ??
+	write_line(obj, GV_POINT, level);
+	break;
+
+
+    case DWG_TYPE_POINT:
+        point = obj->tio.entity->tio.POINT;
+	Vect_append_point(Points, point->x, point->y,
+			  point->z);
+	write_line(obj, GV_POINT, level);
+	break;
+
+    case DWG_TYPE_ARC:
+        arc = obj->tio.entity->tio.ARC;
+	for (ang = arc->start_angle; ang < arc->end_angle;
+	     ang += 2 * LOCPI / 360) {
+	    x = arc->center.x + arc->radius * cos(ang);
+	    y = arc->center.y + arc->radius * sin(ang);
+	    z = arc->center.z + arc->radius;
+	    Vect_append_point(Points, x, y, z);
+	}
+	x = arc->center.x + arc->radius * cos(arc->end_angle);
+	y = arc->center.y + arc->radius * sin(arc->end_angle);
+	z = arc->center.z + arc->radius;
+	Vect_append_point(Points, x, y, z);
+	write_line(obj, GV_LINE, level);
+	break;
+
+    case DWG_TYPE_CIRCLE:
+        circle = obj->tio.entity->tio.CIRCLE;
+	if (circle_flag->answer) {
+	    Vect_append_point(Points, circle->center.x,
+	        circle->center.y, circle->center.z);
+	    write_line(obj, GV_POINT, level);
+	}
+	else {
+	    for (ang = 0; ang < 2 * LOCPI; ang += 2 * LOCPI / 360) {
+                x = circle->center.x + circle->radius * cos(ang);
+                y = circle->center.y + circle->radius * sin(ang);
+                z = circle->center.z + circle->radius;
+		Vect_append_point(Points, x, y, z);
+	    }
+	    Vect_append_point(Points, Points->x[0], Points->y[0],
+			      Points->z[0]);
+	    write_line(obj, GV_LINE, level);
+	}
+	break;
+
+	/* BLOCK starts block of entities but makes no transformation - is it right ? 
+	 *  -> do nothing just warn for xref */
+    case DWG_TYPE_BLOCK:
+        block = obj->tio.entity->tio.BLOCK;
+
+	//FIXME figure out how to do it with LibreDWG
+        /*
+        if (block->namexrefpath[0]) {
+	    G_warning
+		("External reference for block not supported.\n  xref: %s",
+		 ent->block.xrefpath);
+	}
+        */
+	Block = G_store((char*)block->name);
+	break;
+
+    case DWG_TYPE_ENDBLK:	/* endblk - no data */
+	G_free(Block);
+	Block = NULL;
+	break;
+
+    case DWG_TYPE_INSERT:	/* insert */
+        insert = obj->tio.entity->tio.INSERT;
+
+	/* get transformation */
+	/* TODO: fix rotation for CIRCLE and ARC */
+	G_debug(3, " x,y,z: %f, %f, %f", insert->ins_pt.x,
+	    insert->ins_pt.y, insert->ins_pt.z);
+	G_debug(3, " xscale, yscale, zscale: %f, %f, %f", insert->scale.x,
+	    insert->scale.y, insert->scale.z);
+	G_debug(3, " rotang: %f", insert->rotation_ang);
+	/*
+	G_debug(3, " ncols, nrows: %d, %d", ent->insert.numcols,
+		ent->insert.numrows);
+	G_debug(3, " coldist, rowdist: %f, %f", ent->insert.coldist,
+		ent->insert.rowdist);
+        */
+
+	/* write block entities */
+	//FIXME how to check purgedflag?
+	/*
+	if (!adblkh->purgedflag) {
+	    adStartEntityGet(adblkh->entitylist);
+        */
+        printf("Handle do insert: %lu ", obj->handle.value);
+        printf("Handle do block header do insert: %lu\n", insert->block_header->absolute_ref);
+        fflush(stdout);
+
+	//Dwg_Object_BLOCK_HEADER *blockhdr =
+        _obj = insert->block_header->obj;
+        _obj_obj = _obj->tio.object;
+        blockhdr = _obj_obj->tio.BLOCK_HEADER;
+	if (blockhdr->entry_name[0] == ((unsigned char)'*')) //PSPACE OR MSPACE
+	  {
+            printf("Skipping PSPACE or MSPACE block\n");
+            break;
+	  }
+        Dwg_Object *ent = blockhdr->first_entity->obj;
+        while(42)
+          {
+            printf("Dentro do LOOP42\n");
+            if (ent->type == DWG_TYPE_ENDBLK)
+              {
+                printf("Found ENDBLK, breaking\n");
+                break;
+              }
+            else
+              {
+                Trans[level + 1].dx = insert->ins_pt.x;
+                Trans[level + 1].dy = insert->ins_pt.y;
+                Trans[level + 1].dz = insert->ins_pt.z;
+                Trans[level + 1].xscale = insert->scale.x;
+                Trans[level + 1].yscale = insert->scale.y;
+                Trans[level + 1].zscale = insert->scale.z;
+                Trans[level + 1].rotang = insert->rotation_ang;
+                printf("Writing inserted entity. Level = %d\n", level+1);
+                write_entity(ent, objects, ent_counter, level+1);
+                ent = dwg_next_object(ent);
+                if (!ent) break;
+              }
+          }
+        break;
+
+    case DWG_TYPE_SEQEND:	/* seqend */
+	break;
+
+    default:
+          getEntTypeName(obj, buf);
+          G_warning("%s entity not supported", buf);
+	break;
+
+    }				/* end of switch */
+}

Added: grass-addons/vector/v.in.redwg/global.h
===================================================================
--- grass-addons/vector/v.in.redwg/global.h	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/global.h	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,50 @@
+
+/* **************************************************************
+ * 
+ *  MODULE:       v.in.dwg
+ *  
+ *  AUTHOR(S):    Rodrigo Rodrigues da Silva
+ *                based on original code by Radim Blazek
+ *                
+ *  PURPOSE:      Import of DWG/DXF files
+ *                
+ *  COPYRIGHT:    (C) 2001, 2010 by the GRASS Development Team
+ * 
+ *                This program is free software under the 
+ *                GNU General Public License (>=v2). 
+ *                Read the file COPYING that comes with GRASS
+ *                for details.
+ * 
+ * **************************************************************/
+
+/* transformation, first level is 0 ( called from main ) and transformation 
+ *  for this level is 0,0,0, 1,1,1, 0 so that no transformation is done on first level
+ *  (not efective but better readable?) */
+typedef struct
+{
+    double dx, dy, dz;
+    double xscale, yscale, zscale;
+    double rotang;
+} TRANS;
+
+extern int cat;
+extern int n_elements;		/* number of processed elements (only low level elements) */
+extern int n_skipped;		/* number of skipped low level elements (different layer name) */
+extern struct Map_info Map;
+extern dbDriver *driver;
+extern dbString sql;
+extern dbString str;
+extern struct line_pnts *Points;
+extern struct line_cats *Cats;
+extern char *Txt;
+extern char *Block;
+extern struct field_info *Fi;
+extern TRANS *Trans;		/* transformation */
+extern int atrans;		/* number of allocated levels */
+extern struct Option *layers_opt;
+extern struct Flag *invert_flag, *circle_flag;
+
+void write_entity(Dwg_Object *obj, Dwg_Object ** objects,
+      long unsigned int *ent_counter, int level);
+
+int is_low_level(Dwg_Object *obj);

Added: grass-addons/vector/v.in.redwg/main.c
===================================================================
--- grass-addons/vector/v.in.redwg/main.c	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/main.c	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,299 @@
+/* **************************************************************
+ * 
+ *  MODULE:       v.in.redwg
+ *  
+ *  AUTHOR:    Rodrigo Rodrigues da Silva
+ *                based on original code by Radim Blazek
+ *                
+ *  PURPOSE:      Import of DWG files (using free software lib)
+ *                
+ *  COPYRIGHT:    (C) 2001, 2010 by the GRASS Development Team
+ * 
+ *                This program is free software under the 
+ *                GNU General Public License (>=v2). 
+ *                Read the file COPYING that comes with GRASS
+ *                for details.
+ * 
+ * **************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include <dwg.h>
+#include "global.h"
+
+int cat;
+int n_elements;		/* number of processed elements (only low level elements) */
+int n_skipped;		/* number of skipped low level elements (different layer name) */
+struct Map_info Map;
+dbDriver *driver;
+dbString sql;
+dbString str;
+struct line_pnts *Points;
+struct line_cats *Cats;
+char *Txt;
+char *Block;
+struct field_info *Fi;
+TRANS *Trans;		/* transformation */
+int atrans;		/* number of allocated levels */
+struct Option *layers_opt;
+struct Flag *invert_flag, *circle_flag;
+
+int import_object(Dwg_Object * obj);
+
+void list_layers(Dwg_Data * dwg);
+
+int main(int argc, char *argv[])
+{
+    struct GModule *module;
+    struct Option *out_opt, *in_opt;
+    struct Flag *z_flag, *l_flag, *int_flag;
+    char buf[2000];
+    long unsigned int i;
+    short initerror;
+
+    /* DWG */
+    Dwg_Data dwg;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("import"));
+    module->description = _("Converts DWG to GRASS vector map");
+
+    in_opt = G_define_standard_option(G_OPT_F_INPUT);
+    in_opt->description = _("Name of DWG file");
+
+    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
+    out_opt->required = YES;
+
+    layers_opt = G_define_option();
+    layers_opt->key = "layers";
+    layers_opt->type = TYPE_STRING;
+    layers_opt->required = NO;
+    layers_opt->multiple = YES;
+    layers_opt->description = _("List of layers to import");
+
+    invert_flag = G_define_flag();
+    invert_flag->key = 'i';
+    invert_flag->description =
+	_("Invert selection by layers (don't import layers in list)");
+
+    z_flag = G_define_flag();
+    z_flag->key = 'z';
+    z_flag->description = _("Create 3D vector map");
+
+    circle_flag = G_define_flag();
+    circle_flag->key = 'c';
+    circle_flag->description = _("Write circles as points (centre)");
+
+    l_flag = G_define_flag();
+    l_flag->key = 'l';
+    l_flag->description = _("List available layers and exit");
+
+    int_flag = G_define_flag();
+    int_flag->key = 'n';
+    int_flag->description = _("Use numeric type for attribute \"layer\"");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    db_init_string(&sql);
+    db_init_string(&str);
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    Block = NULL;
+
+    atrans = 20;		/* nested, recursive levels */
+    Trans = (TRANS *) G_malloc(atrans * sizeof(TRANS));
+
+    /* Init LibreDWG, load file */
+
+    initerror = dwg_read_file(in_opt->answer, &dwg);
+
+    if(initerror) {
+      sprintf(buf, _("Unable to initialize LibreDWG. Error: %d."),
+                      initerror);
+      sprintf(buf, _("Unable to load file %s"), in_opt->answer);
+      G_fatal_error(buf);
+    }
+
+
+    //List layers (if option chosen)
+    if (l_flag->answer) {
+      list_layers(&dwg);
+      //XXX: should I really exit? maybe other options should be checked
+      exit(EXIT_SUCCESS);
+    }
+
+    /* open output vector */
+    Vect_open_new(&Map, out_opt->answer, z_flag->answer);
+
+    Vect_hist_command(&Map);
+
+    /* Add DB link */
+    Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
+    Vect_map_add_dblink(&Map, 1, NULL, Fi->table, "cat", Fi->database,
+			Fi->driver);
+
+    driver =
+	db_start_driver_open_database(Fi->driver,
+				      Vect_subst_var(Fi->database, &Map));
+    if (driver == NULL) {
+	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+		      Vect_subst_var(Fi->database, &Map), Fi->driver);
+    }
+    db_begin_transaction(driver);
+
+    /* Create table */
+    if (int_flag->answer) {	/* List layers */
+	sprintf(buf,
+		"create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
+		"layer real, block varchar(100), txt varchar(100) )",
+		Fi->table);
+
+    }
+    else {
+	sprintf(buf,
+		"create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
+		"layer varchar(100), block varchar(100), txt varchar(100) )",
+		Fi->table);
+    }
+    db_set_string(&sql, buf);
+    G_debug(3, db_get_string(&sql));
+
+    if (db_execute_immediate(driver, &sql) != DB_OK) {
+	db_close_database(driver);
+	db_shutdown_driver(driver);
+	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
+    }
+
+    if (db_create_index2(driver, Fi->table, "cat") != DB_OK)
+	G_warning(_("Unable to create index for table <%s>, key <%s>"),
+		  Fi->table, "cat");
+
+    if (db_grant_on_table
+	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
+	G_fatal_error(_("Unable to grant privileges on table <%s>"),
+		      Fi->table);
+
+    cat = 1;
+    n_elements = n_skipped = 0;
+
+    /* Write each entity. Some entities may be composed by other entities (like INSERT or BLOCK) */
+    /* Set transformation for first (index 0) level */
+    Trans[0].dx = Trans[0].dy = Trans[0].dz = 0;
+    Trans[0].xscale = Trans[0].yscale = Trans[0].zscale = 1;
+    Trans[0].rotang = 0;
+
+
+    for(i=0; i < dwg_get_object_count(&dwg); i++)
+      {
+        fprintf(stdout, "Type: %u\n", dwg.object[i].type);
+      }
+    fprintf(stdout, "%lu objects\n", dwg_get_object_count(&dwg));
+    fflush(stdout);
+
+    for (i = 0; i < dwg_get_object_count(&dwg); i++)
+    {
+      if (import_object(&dwg.object[i]))
+        {
+          //pass i pointer since write_entity may process more than one entity
+          write_entity(&dwg.object[i], &dwg.object, &i, 0);
+        }
+    }
+
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    Vect_build(&Map);//, stderr);
+    Vect_close(&Map);
+    
+    if (n_skipped > 0)
+	G_message(_("%d elements skipped (layer name was not in list)"),
+		  n_skipped);
+    
+    G_done_msg(_("%d elements processed"), n_elements);
+
+    exit(EXIT_SUCCESS);
+}
+
+void
+list_layers(Dwg_Data * dwg)
+{
+  int i;
+  long unsigned int l_count = dwg_get_layer_count(dwg);
+
+  G_debug(2, "%lu layers\n", l_count);
+  fprintf(stdout, "%lu layers\n", l_count);
+
+  Dwg_Object_LAYER **layers = dwg_get_layers(dwg);
+
+  for (i=0; i<l_count; i++) {
+    fprintf(stdout, "NAME: %s COLOR: %lu STATE: ", layers[i]->entry_name,
+          layers[i]->color.rgb);
+    if (layers[i]->on)
+        fprintf(stdout, "ON, ");
+    else
+        fprintf(stdout, "OFF, ");
+    if (layers[i]->frozen)
+        fprintf(stdout, "FROZEN, ");
+    else
+        fprintf(stdout, "THAWED, ");
+    if(layers[i]->locked)
+        fprintf(stdout, "LOCKED\n");
+    else
+        fprintf(stdout, "UNLOCKED\n");
+  }
+  G_free(layers);
+}
+
+int
+import_object(Dwg_Object * obj)
+{
+  if (obj->supertype != DWG_SUPERTYPE_ENTITY)
+    return 0;
+
+  if (layers_opt->answers)
+    {
+      Dwg_Object_LAYER * layer = dwg_get_entity_layer(obj->tio.entity);
+      int i = 0;
+      int layer_found = 0;
+      //FIXME check if layer is purged
+      if (42 /*layer->purgedflag*/)
+        {
+          while (layers_opt->answers[i])
+            {
+              if (strcmp((char*)layer->entry_name, layers_opt->answers[i]) == 0)
+                {
+                  layer_found = 1;
+                  break;
+                }
+              i++;
+            }
+        }
+
+      if ((!invert_flag->answer && !layer_found) || (invert_flag->answer
+          && layer_found))
+        {
+          if (is_low_level(obj))
+            n_skipped++;
+          if (obj->type != DWG_TYPE_INSERT &&
+              obj->type != DWG_TYPE_POLYLINE_2D &&
+              obj->type != DWG_TYPE_POLYLINE_3D &&
+              obj->type != DWG_TYPE_POLYLINE_MESH &&
+              obj->type != DWG_TYPE_POLYLINE_PFACE)
+            return 0;
+        }
+    }
+  return 1;
+}

Added: grass-addons/vector/v.in.redwg/v.in.redwg.html
===================================================================
--- grass-addons/vector/v.in.redwg/v.in.redwg.html	                        (rev 0)
+++ grass-addons/vector/v.in.redwg/v.in.redwg.html	2010-08-20 22:32:09 UTC (rev 43170)
@@ -0,0 +1,37 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.in.redwg</em> imports DWG files into GRASS.
+
+<h2>EXAMPLE</h2>
+<div class="code"><pre>
+v.in.redwg input=map.dwg output=map
+</pre></div>
+
+<h2>NOTES</h2>
+
+v.in.redwg <strong>does not require OpenDWG or any proprietary software<strong>.
+It requires <a href="http://www.gnu.org/s/libredwg">LibreDWG</a>, which
+is released under the GNU GPLv3.
+<P>
+You need to download, compile and install (check website) LibreDWG and use the 
+related <tt>configure</tt> options to tell GRASS about it (warning: configure
+options not implemented yet)
+
+<div class="code"><pre>
+   ./configure \
+   ... \
+   --with-libredwg \
+   --with-libredwg-includes=/usr/include \
+</pre></div>
+
+Then run <i>make</i> to compile this module.
+<P>
+Not all entity types are supported (warning printed).
+
+
+<h2>AUTHOR</h2>
+
+Rodrigo Rodrigues da Silva (pitanga at members dot fsf dot org), São Paulo, Brazil
+<br>based on original code by Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date: 2009-12-21 02:09:42 -0300 (Mon, 21 Dec 2009) $</i>



More information about the grass-commit mailing list