// DXF Insert -> SVG char* insert2group(insert in, int precision, char * units, double scaling, tables plot_info, blocks blks, char *out){ char *out_ptr; char tmp_char[100000]; // get the block using the name from the insert information block blk = blks.ret_block(in.name(tmp_char)); entity *ent_ptr = ∈ entities *ents_ptr = &blk; // For now just translations MBS 22 Aug 05 strcpy(out, "<g transform=\"matrix(1,0,0,1,"); strcat(out,gcvt(scaling*ent_ptr->ret_x(),precision,tmp_char) ); strcat(out,","); strcat(out,gcvt(-scaling*ent_ptr->ret_y(),precision,tmp_char) ); strcat(out,")\" >\n"); // Now convert the entities in the block std::vector< polyline > plines = ents_ptr->ret_plines(); std::vector< lwpolyline > lwplines = ents_ptr->ret_lwplines(); std::vector< arc > arcs = ents_ptr->ret_arcs(); std::vector< circle > circs = ents_ptr->ret_circles(); std::vector< line > lns = ents_ptr->ret_lines(); std::vector< text > txts = ents_ptr->ret_texts(); for(int i = 0; i < plines.size();i++){ strcat( out,pline2pline(plines[i], units, scaling, plot_info ) ); strcat( out, "\n" ); } for(int i = 0; i < lwplines.size();i++){ strcat( out,lwpline2path(lwplines[i], units, scaling, plot_info ) ); strcat( out, "\n" ); } for(int i = 0; i < arcs.size();i++){ strcat( out, arc2path(arcs[i], 6,units, scaling, plot_info, tmp_char ) ); strcat( out, "\n" ); } for(int i = 0; i < circs.size();i++){ strcat( out, circle2circle(circs[i], 6, units, scaling, plot_info, tmp_char) ); strcat( out, "\n" ); } for(int i = 0; i < lns.size();i++){ strcat( out, line2line(lns[i], 6, units, scaling, plot_info, tmp_char) ); strcat( out, "\n" ); } for(int i = 0; i < txts.size();i++){ strcat( out, text2text(txts[i], 6, units, scaling, plot_info, tmp_char) ); strcat( out, "\n" ); } // End the group strcat(out,"</g>"); out_ptr = out; return out_ptr; }
char* write_all(int output_type, entities &ents, tables &tbls, blocks &blks, double scaling, char * units, char * out){ // output_type = 0 is to std:out // output_type = 1 is to the input filename but with .dxf on the end // For now everything will go to stdout later may directed to other places // Get the various file informations as dependent on the layer type std::vector< polyline > plines = ents.ret_plines(); std::vector< lwpolyline > lwplines = ents.ret_lwplines(); std::vector< arc > arcs = ents.ret_arcs(); std::vector< circle > circs = ents.ret_circles(); std::vector< line > lns = ents.ret_lines(); std::vector< text > txts = ents.ret_texts(); std::vector< insert > ins = ents.ret_inserts(); // It would be better to redirect stdout to different places. That would make the code cleaner but I don't think it will work better char tmp_char[100000]; for(int i = 0; i < plines.size();i++){ if (output_type == 0){ std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl; } else if (output_type == 1){ std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl; } } for(int i = 0; i < lwplines.size();i++){ if (output_type == 0){ std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl; } else if (output_type == 1){ std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl; } } for(int i = 0; i < arcs.size();i++){ if (output_type == 0){ std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl; } else if (output_type == 1){ std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl; } } for(int i = 0; i < circs.size();i++){ if (output_type == 0){ std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl; } else if (output_type == 1){ std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl; } } for(int i = 0; i < lns.size();i++){ if (output_type == 0){ std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl; } else if (output_type == 1){ std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl; } } for(int i = 0; i < txts.size();i++){ if (output_type == 0){ std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl; } else if (output_type == 1){ std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl; } } for(int i = 0; i < ins.size();i++){ if (output_type == 0){ std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl; } else if (output_type == 1){ std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl; } } }
/* shortest distance between line and area * return 1 inside area * return 2 inside isle of area * return 3 outside area */ int line2area(const struct Map_info *To, struct line_pnts *Points, int type, int area, const struct bound_box *abox, double *fx, double *fy, double *fz, double *falong, double *fangle, double *tx, double *ty, double *tz, double *talong, double *tangle, double *dist, int with_z) { int i, j; double tmp_dist; int isle, nisles; int all_inside_outer, all_outside_outer, all_outside_inner; static struct line_pnts *aPoints = NULL; static struct line_pnts **iPoints = NULL; static struct bound_box *ibox = NULL; static int isle_alloc = 0; if (!aPoints) aPoints = Vect_new_line_struct(); *dist = PORT_DOUBLE_MAX; /* fangle and tangle are angles in radians, counter clockwise from x axis * initialize to invalid angle */ *fangle = *tangle = -9.; *falong = *talong = 0.; *fx = Points->x[0]; *fy = Points->y[0]; *fz = Points->z[0]; *tx = Points->x[0]; *ty = Points->y[0]; *tz = Points->z[0]; Vect_get_area_points(To, area, aPoints); nisles = Vect_get_area_num_isles(To, area); if (nisles > isle_alloc) { iPoints = G_realloc(iPoints, nisles * sizeof(struct line_pnts *)); ibox = G_realloc(ibox, nisles * sizeof(struct bound_box)); for (i = isle_alloc; i < nisles; i++) iPoints[i] = Vect_new_line_struct(); isle_alloc = nisles; } for (i = 0; i < nisles; i++) { isle = Vect_get_area_isle(To, area, i); Vect_get_isle_points(To, isle, iPoints[i]); Vect_get_isle_box(To, isle, &ibox[i]); } /* inside area ? */ all_inside_outer = all_outside_outer = 1; all_outside_inner = 1; int in_box; for (i = 0; i < Points->n_points; i++) { if (with_z) in_box = Vect_point_in_box(Points->x[i], Points->y[i], Points->z[i], abox); else in_box = Vect_point_in_box_2d(Points->x[i], Points->y[i], abox); if (in_box) { int poly; poly = Vect_point_in_poly(Points->x[i], Points->y[i], aPoints); if (poly > 0) { /* inside outer ring */ all_outside_outer = 0; } else { /* outside outer ring */ all_inside_outer = 0; } /* exactly on boundary */ if (poly == 2) { line2line(Points, type, aPoints, GV_BOUNDARY, fx, fy, fz, falong, fangle, tx, ty, tz, talong, tangle, dist, with_z); *talong = 0; *tangle = -9; return 1; } /* inside outer ring */ else if (poly == 1) { int inside_isle = 0; for (j = 0; j < nisles; j++) { if (with_z) in_box = Vect_point_in_box(Points->x[i], Points->y[i], Points->z[i], &ibox[j]); else in_box = Vect_point_in_box_2d(Points->x[i], Points->y[i], &ibox[j]); if (in_box) { poly = Vect_point_in_poly(Points->x[i], Points->y[i], iPoints[j]); /* inside or exactly on boundary */ if (poly > 0) { double tmp_fx, tmp_fy, tmp_fz, tmp_fangle, tmp_falong; double tmp_tx, tmp_ty, tmp_tz, tmp_tangle, tmp_talong; /* pass all points of the line, * this will catch an intersection */ line2line(Points, type, iPoints[j], GV_BOUNDARY, &tmp_fx, &tmp_fy, &tmp_fz, &tmp_falong, &tmp_fangle, &tmp_tx, &tmp_ty, &tmp_tz, &tmp_talong, &tmp_tangle, &tmp_dist, with_z); if (*dist > tmp_dist) { *dist = tmp_dist; *fx = tmp_fx; *fy = tmp_fy; *fz = tmp_fz; *falong = tmp_falong; *fangle = tmp_fangle; *tx = tmp_tx; *ty = tmp_ty; *tz = tmp_tz; *talong = 0; *tangle = tmp_tangle; } if (poly == 1) /* excludes isle boundary */ inside_isle = 1; } } if (*dist == 0) break; } /* inside area (inside outer ring, outside inner rings * or exactly on one of the inner rings) */ if (!inside_isle) { *fx = Points->x[i]; *fy = Points->y[i]; *fz = Points->z[i]; *tx = Points->x[i]; *ty = Points->y[i]; *tz = Points->z[i]; *fangle = *tangle = -9.; *falong = *talong = 0.; *dist = 0; return 1; } else { /* inside one of the islands */ all_outside_inner = 0; if (*dist == 0) { /* the line intersected with the isle boundary * -> line is partially inside the area */ *fangle = *tangle = -9.; *falong = *talong = 0.; return 1; } /* else continue with next point */ } } /* end inside outer ring */ } else { /* point not in box of outer ring */ all_inside_outer = 0; } /* exactly on boundary */ if (*dist == 0) return 1; } /* if all points are inside the outer ring and inside inner rings, * there could still be an intersection with one of the inner rings */ if (all_inside_outer) { if (all_outside_inner) { /* at least one point is really inside the area! * that should have been detected above */ G_fatal_error(_("At least one point is really inside the area!")); } /* else all points are inside one of the area isles * and we already have the minimum distance */ return 2; } /* if at least one point was found to be inside the outer ring, * but no point really inside the area, * and at least one point outside, * then there must be an intersection of the line with both * the outer ring and one of the isle boundaries */ /* if all line points are outside of the area, * intersection is still possible */ line2line(Points, type, aPoints, GV_BOUNDARY, fx, fy, fz, falong, fangle, tx, ty, tz, talong, tangle, dist, with_z); *talong = 0; if (*dist == 0) return 1; return 3; }