Exemplo n.º 1
0
/**
 * Write the TIN to a TIN (.itf) file (VTP-defined format).
 */
bool vtTin::Write(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	char *wkt;
	OGRErr err = m_proj.exportToWkt(&wkt);
	if (err != OGRERR_NONE)
	{
		fclose(fp);
		return false;
	}
	int proj_len = strlen(wkt);
	int data_start = 5 + 4 + 4 + 4 + + 4 + proj_len + 32 + 4 + 4;

	int i;
	int verts = NumVerts();
	int tris = NumTris();

	fwrite("tin02", 5, 1, fp);	// version 2
	fwrite(&verts, 4, 1, fp);
	fwrite(&tris, 4, 1, fp);
	fwrite(&data_start, 4, 1, fp);
	fwrite(&proj_len, 4, 1, fp);
	fwrite(wkt, proj_len, 1, fp);
	OGRFree(wkt);

	// version 2 of the format has extents: left, top, right, bottom, min z, max h
	fwrite(&m_EarthExtents.left, sizeof(double), 4, fp);
	fwrite(&m_fMinHeight, sizeof(float), 1, fp);
	fwrite(&m_fMaxHeight, sizeof(float), 1, fp);

	// room for future extention: you can add fields here, as long as you
	// increase the data_start offset above accordingly

	// count progress
	int count = 0, total = verts + tris;

	// write verts
	for (i = 0; i < verts; i++)
	{
		fwrite(&m_vert[i].x, 8, 2, fp);	// 2 doubles
		fwrite(&m_z[i], 4, 1, fp);		// 1 float

		if (progress_callback && (++count % 100) == 0)
			progress_callback(count * 99 / total);
	}
	// write tris
	for (i = 0; i < tris; i++)
	{
		fwrite(&m_tri[i*3], 4, 3, fp);	// 3 ints

		if (progress_callback && (++count % 100) == 0)
			progress_callback(count * 99 / total);
	}

	fclose(fp);
	return true;
}
Exemplo n.º 2
0
void Countries::WriteGCF(const char *fname)
{
	FILE *fp = vtFileOpen(fname, "wb");

	int num = m_countries.GetSize();
	fwrite(&num, sizeof(int), 1, fp);

	int i, j, num_places;
	for (i = 0; i < num; i++)
	{
		Country *country = m_countries[i];
		num_places = country->m_places.GetSize();

		WriteString(fp, country->m_full);
		fwrite(&num_places, sizeof(int), 1, fp);

		for (j = 0; j < num_places; j++)
		{
			Place *place = country->m_places[j];
			fwrite(&place->m_pos.x, sizeof(double), 2, fp);
			WriteString(fp, place->m_fullname_nd);
		}
	}
	fclose(fp);
}
Exemplo n.º 3
0
bool Gazetteer::ReadZips(const char *fname)
{
	// safety checks
	if (!fname)
		return false;
	if (*fname == 0)
		return false;

	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	vtString str;
	char buf[999];
	while (fgets(buf, 999, fp) != NULL)
	{
		Zip p;

		str = Grab(buf, 2, 5);
		if (str[4] == 'H' || str[4] == 'X')
			continue;

		p.m_zip = atoi(str);

		double x = atof(buf+146);
		double y = atof(buf+136);
		p.geo.Set(x, y);

		m_zips.push_back(p);
	}

	fclose(fp);
	return true;
}
Exemplo n.º 4
0
bool Gazetteer::ReadPlaces(const char *fname)
{
	// safety checks
	if (!fname)
		return false;
	if (*fname == 0)
		return false;

	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	char buf[999];
	while (fgets(buf, 999, fp) != NULL)
	{
		Place p;
		p.m_state = Grab(buf, 0, 2);
		p.m_name = Grab(buf, 9, 60);
		p.m_name.TrimRight();

		if (p.m_name.Right(10) == " (balance)")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 10);

		if (p.m_name.Right(5) == " city")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 5);
		else if (p.m_name.Right(5) == " town")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 5);
		else if (p.m_name.Right(4) == " CDP")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 4);
		else if (p.m_name.Right(13) == " municipality")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 13);
		else if (p.m_name.Right(17) == " city and borough")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 17);
		else if (p.m_name.Right(8) == " borough")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 8);
		else if (p.m_name.Right(8) == " village")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 8);
		else if (p.m_name.Right(10) == " comunidad")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 10);
		else if (p.m_name.Right(12) == " zona urbana")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 12);
		else if (p.m_name.Right(7) == " urbana")
			p.m_name = p.m_name.Left(p.m_name.GetLength() - 7);
		else
		{
			int foo = 1;
		}
		double x = atof(buf+153);
		double y = atof(buf+143);
		p.geo.Set(x, y);

		m_places.push_back(p);
	}
	fclose(fp);
	return true;
}
Exemplo n.º 5
0
bool vtUnzip::ExtractAccept(const char *write_filename, bool bOverwrite)
{
	bool bOK = true;
	if (!bOverwrite)
	{
		FILE* file = vtFileOpen(write_filename, "rb");
		bool bExisting = (file != NULL);
		if (file != NULL) fclose(file);
		bOK = !bExisting;
	}
	return bOK;
}
Exemplo n.º 6
0
/**
 * Write the TIN to a Wavefront OBJ file.  Note that we write X and Y as
 * geographic coordinates, but OBJ only supports single-precision floating
 * point values, so it may lose some precision.
 */
bool vtTin::WriteOBJ(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	int i, count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	fprintf(fp, "####\n");
	fprintf(fp, "#\n");
	fprintf(fp, "# OBJ File Generated by VTBuilder\n");
	fprintf(fp, "#\n");
	fprintf(fp, "####\n");
	fprintf(fp, "# Object %s\n", fname);
	fprintf(fp, "#\n");
	fprintf(fp, "# Vertices: %d\n", verts);
	fprintf(fp, "# Faces: %d\n", tris);
	fprintf(fp, "#\n");
	fprintf(fp, "####\n");

	// write verts
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "v %lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "# %d vertices, 0 vertices normals\n", verts);
	fprintf(fp, "\n");

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is     triangle definition (zero based)  A B C ...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "f %d %d %d\n", m_tri[i*3+0]+1, m_tri[i*3+1]+1, m_tri[i*3+2]+1);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "# %d faces, 0 coords texture\n", tris);
	fprintf(fp, "\n");
	fprintf(fp, "# End of File\n");
	fclose(fp);
	return true;
}
Exemplo n.º 7
0
bool ColorMap::Load(const char *fname)
{
	// watch out for %f
	LocaleWrap normal_numbers(LC_NUMERIC, "C");

	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	char buf[80];
	fgets(buf, 80, fp);
	if (strncmp(buf, "colormap1", 9))
		return false;

	while (fgets(buf, 80, fp) != NULL)
	{
		int ival;
		if (!strncmp(buf, "blend", 5))
		{
			sscanf(buf, "blend: %d\n", &ival);
			m_bBlend = (ival != 0);
		}

		else if (!strncmp(buf, "relative", 8))
		{
			sscanf(buf, "relative: %d\n", &ival);
			m_bRelative = (ival != 0);
		}

		else if (!strncmp(buf, "size", 4))
		{
			int size;
			sscanf(buf, "size %d\n", &size);

			m_elev.resize(size);
			m_color.resize(size);
			for (int i = 0; i < size; i++)
			{
				float f;
				short r, g, b;
				fscanf(fp, "\telev %f color %hd %hd %hd\n", &f, &r, &g, &b);
				m_elev[i] = f;
				m_color[i].Set(r, g, b);
			}
		}
	}
	fclose(fp);
	return true;
}
Exemplo n.º 8
0
/**
 * Read the TIN body from a native TIN format (.itf) file.  You should
 * first call ReadHeader() if you are doing a two-part read.
 */
bool vtTin::ReadBody(const char *fname, bool progress_callback(int))
{
	// first read the point from the .tin file
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	bool success = _ReadTinBody(fp, progress_callback);
	fclose(fp);

	if (!success)
		return false;

	return true;
}
Exemplo n.º 9
0
/**
 * Read the TIN header from a native TIN format (.itf).  Reading the header is
 * quick and lets you query properties (NumVerts, NumTris, GetEarthExtents)
 * before loading the rest of the file.
 */
bool vtTin::ReadHeader(const char *fname)
{
	// first read the point from the .tin file
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	bool success = _ReadTinHeader(fp);
	fclose(fp);

	if (!success)
		return false;

	return true;
}
Exemplo n.º 10
0
/**
 * Read a image file into the DIB.  This method will check to see if the
 * file is a BMP or JPEG and call the appropriate reader.
 */
bool vtDIB::Read(const char *fname, bool progress_callback(int))
{
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;
	uchar buf[2];
	if (fread(buf, 2, 1, fp) != 1)
		return false;
	fclose(fp);
	if (buf[0] == 0x42 && buf[1] == 0x4d)
		return ReadBMP(fname, progress_callback);
	else if (buf[0] == 0xFF && buf[1] == 0xD8)
		return ReadJPEG(fname, progress_callback);
	else if (buf[0] == 0x89 && buf[1] == 0x50)
		return ReadPNG(fname, progress_callback);
	return false;
}
Exemplo n.º 11
0
//
// data is saved in JPEG format
// \param quality	JPEG quality in the range of 0..100.
//
bool MiniDatabuf::savedataJPEG(const char *filename, int quality)
{
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;

	FILE *outfile = vtFileOpen(filename, "wb");
	if (outfile == NULL)
		return false;

	/* Initialize the JPEG decompression object with default error handling. */
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);

	/* Specify data source for decompression */
	jpeg_stdio_dest(&cinfo, outfile);

	// set parameters for compression
	cinfo.image_width = xsize;	/* image width and height, in pixels */
	cinfo.image_height = ysize;
	cinfo.input_components = 3;	/* # of color components per pixel */
	cinfo.in_color_space = JCS_RGB;	/* colorspace of input image */

	// Now use the library's routine to set default compression parameters.
	jpeg_set_defaults(&cinfo);

	jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);

	/* Start compressor */
	jpeg_start_compress(&cinfo, TRUE);

	/* Process each scanline */
	int row_stride = cinfo.image_width * cinfo.input_components;
	while (cinfo.next_scanline < cinfo.image_height)
	{
		JSAMPROW row_buffer = (JSAMPROW)data + cinfo.next_scanline * row_stride;
		jpeg_write_scanlines(&cinfo, &row_buffer, 1);
	}
	jpeg_finish_compress(&cinfo);

	/* After finish_compress, we can close the output file. */
	fclose(outfile);

	jpeg_destroy_compress(&cinfo);

	return true;
}
Exemplo n.º 12
0
/**
 * Write the TIN to a Stanford Polygon File Format (PLY),
 * http://en.wikipedia.org/wiki/PLY_(file_format)
 */
bool vtTin::WritePLY(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	int i, count = 0;
	int verts = NumVerts();
	int tris = NumTris();
	int total = verts + tris;

	fprintf(fp, "ply\n");
	fprintf(fp, "format ascii 1.0\n");
	fprintf(fp, "comment VTBuilder generated\n");
	fprintf(fp, "element vertex %d\n", verts);
	fprintf(fp, "property float x\n");
	fprintf(fp, "property float y\n");
	fprintf(fp, "property float z\n");
	fprintf(fp, "element face %d\n", tris);
	fprintf(fp, "property list uchar int vertex_indices\n");
	fprintf(fp, "end_header\n");

	// write verts
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is  triangle definition (zero based)  A B C ...
		fprintf(fp, "3 %d %d %d\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fclose(fp);
	return true;
}
Exemplo n.º 13
0
//
// helper - read a LF-delimited DEM and write it with fixed-length records
//
bool ConvertDLG_from_LFDelim(const char *fname_from, const char *fname_to)
{
	FILE *out = vtFileOpen(fname_to, "wb");
	if (!out) return false;

	char buf[160];

	vtDLGFile in;
	in.Read(fname_from);
	if (!in.m_iError) {
		in.OpenFile();
		while (in.GetRecord(buf))
		{
			fwrite(buf, 80, 1, out);
		}
		in.CloseFile();
	}
	fclose(out);
	return true;
}
Exemplo n.º 14
0
/**
 * Write the TIN to the GMS format.  Historically GMS stood for 'Groundwater
 * Modeling System' from the EMS-I company, now called Aquaveo.
 */
bool vtTin::WriteGMS(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	// first line is file identifier
	fprintf(fp, "TIN\n");
	fprintf(fp, "BEGT\n");
	fprintf(fp, "ID 1\n");			// Indices start at 1
	//fprintf(fp, "TNAM tin\n");	// "name" of the TIN; optional
	//fprintf(fp, "MAT 1\n");		// "TIN material ID"; optional

	int count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// write verts
	fprintf(fp, "VERT %d\n", verts);
	for (int i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	// write tris
	fprintf(fp, "TRI %d\n", tris);
	for (int i = 0; i < tris; i++)
	{
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d\n", m_tri[i*3+0]+1, m_tri[i*3+1]+1, m_tri[i*3+2]+1);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "ENDT\n");
	fclose(fp);
	return true;
}
Exemplo n.º 15
0
bool ColorMap::Save(const char *fname) const
{
	// watch out for %f
	LocaleWrap normal_numbers(LC_NUMERIC, "C");

	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;
	fprintf(fp, "colormap1\n");
	fprintf(fp, "blend: %d\n", m_bBlend);
	fprintf(fp, "relative: %d\n", m_bRelative);
	int size = m_elev.size();
	fprintf(fp, "size %d\n", size);
	for (int i = 0; i < size; i++)
	{
		fprintf(fp, "\telev %f color %d %d %d\n", m_elev[i],
			m_color[i].r, m_color[i].g, m_color[i].b);
	}
	fclose(fp);
	return true;
}
Exemplo n.º 16
0
bool Countries::ReadCountryList(const char *fname)
{
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	int off;
	vtString str, name, abb;
	char buf[400];
	while (fgets(buf, 400, fp) != NULL)
	{
		str = buf;
		off = str.Find(':');
		Country *country = new Country;
		country->m_full = str.Left(off);
		country->m_abb = str.Mid(off+1, 2);
		m_countries.Append(country);
	}
	fclose(fp);
	return true;
}
Exemplo n.º 17
0
bool Countries::ReadGCF(const char *fname, bool progress_callback(int))
{
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	int num;
	fread(&num, sizeof(int), 1, fp);

	m_countries.SetMaxSize(num);

	int i, j, num_places;
	for (i = 0; i < num; i++)
	{
		if (progress_callback != NULL)
			progress_callback(i * 100 / num);

		Country *country = new Country;
		m_countries.Append(country);

		ReadString(fp, country->m_full);
		printf("Reading %s...\n", (const char *) country->m_full);

		fread(&num_places, sizeof(int), 1, fp);
		country->m_places.SetMaxSize(num_places);

		for (j = 0; j < num_places; j++)
		{
			Place *place = new Place;
			fread(&place->m_pos.x, sizeof(double), 2, fp);
			ReadString(fp, place->m_fullname_nd);
			country->m_places.Append(place);
		}
	}
	fclose(fp);
	return true;
}
Exemplo n.º 18
0
bool vtDLGFile::Read(const char *fname, bool progress_callback(int))
{
	char buf[80];
	int i, j, iUTMZone;

	// basic initialization
	m_iError = 0;

	m_fname = fname;
	m_fp = vtFileOpen(fname, "rb");
	if (!m_fp)
	{
		m_iError = DLG_ERR_FILE;
		return false;
	}

	// check to see if this is a LF-delimited file
	m_bLFdelimited = false;
	fseek(m_fp, 56, SEEK_SET);
	for (i = 0; i < 24; i++)
	{
		if (fgetc(m_fp) == 10)
			m_bLFdelimited = true;
	}

	// rewind to beginning
	fseek(m_fp, 0, SEEK_SET);

	// record 1 - banner
	if (!GetRecord(buf)) return false;
	strncpy(m_header, buf, 72);

	// record 2 - cell name, date, qualifier, scale, sectional indicator
	if (!GetRecord(buf)) return false;

	// record 3 - contour interval info, status flags
	if (!GetRecord(buf)) return false;

	// record 4 - codes, resolution, transformation info
	if (!GetRecord(buf)) return false;
	int reference_system = geti6(buf + 6);	// 1 = UTM, 3 = Albers
	if (reference_system == 3)	// We don't support Albers
		return false;
	iUTMZone = geti6(buf + 12);

	// Datum.  Undocumented field!  Had to look at the government's
	// own "dlgv32" source to figure out how to find this value.
	int iDLGDatum = geti3(buf + 66);

	// safety check.. because they do
	if ((iDLGDatum < 0) || (iDLGDatum > 4))
		iDLGDatum = 0;

	// this is how they interpret the value
	int iDatum;
	switch (iDLGDatum)
	{
		case 0:
			iDatum = EPSG_DATUM_NAD27;
			break;
		case 1:
			iDatum = EPSG_DATUM_NAD83;
			break;
		default:
			iDatum = -1;
			break;
	}

	// record 5-9 - Projection parameters for map transformation
	for (i = 5; i < 10; i++)
		if (!GetRecord(buf)) return false;

	// record 10 - Internal file-to-map projection transformation parameters
	if (!GetRecord(buf)) return false;

	// record 11 - SW quadrangle corner
	if (!GetRecord(buf)) return false;
	m_SW_lat.y = getd12(buf+6);
	m_SW_lat.x = getd12(buf+18);
	m_SW_utm.x = getd12(buf+36);
	m_SW_utm.y = getd12(buf+48);

	// record 12 - NW quadrangle corner
	if (!GetRecord(buf)) return false;
	m_NW_lat.y = getd12(buf+6);
	m_NW_lat.x = getd12(buf+18);
	m_NW_utm.x = getd12(buf+36);
	m_NW_utm.y = getd12(buf+48);

	// record 13 - NE quadrangle corner
	if (!GetRecord(buf)) return false;
	m_NE_lat.y = getd12(buf+6);
	m_NE_lat.x = getd12(buf+18);
	m_NE_utm.x = getd12(buf+36);
	m_NE_utm.y = getd12(buf+48);

	// record 14 - SE quadrangle corner
	if (!GetRecord(buf)) return false;
	m_SE_lat.y = getd12(buf+6);
	m_SE_lat.x = getd12(buf+18);
	m_SE_utm.x = getd12(buf+36);
	m_SE_utm.y = getd12(buf+48);

	// Special exception: DLG for Hawai`i that says "NAD27" is actually in
	// Old Hawaiian Datum (OHD) - so check for it.
	if ((iUTMZone == 4 || iUTMZone == 5) && m_SW_utm.y < 3500000)
	{
		if (iDatum == EPSG_DATUM_NAD27)
			iDatum = EPSG_DATUM_OLD_HAWAIIAN;
	}

	// We now know enough to set the projection.
	m_proj.SetProjectionSimple(true, iUTMZone, iDatum);

	// record 15 - category name, attribute format code, number of nodes...
	if (!GetRecord(buf)) return false;
	m_iNodes = geti6(buf + 24);
	m_iAreas = geti6(buf + 40);
	m_iLines = geti6(buf + 56);

	// allocate storage space
	m_nodes.resize(m_iNodes);
	m_areas.resize(m_iAreas);
	m_lines.resize(m_iLines);

	int total = m_iNodes + m_iAreas + m_iLines, elem = 0;

	// now read the nodes
	for (i = 0; i < m_iNodes; i++)
	{
		if (!GetRecord(buf)) return false;

		// do some safety checking
		if (buf[0] != 'N') break;		// make sure node starts with a N
		int id = geti6(buf + 1);
		if (id != i+1) break;		// got the right node number?

		m_nodes[i].m_p.x = getd12(buf+6);
		m_nodes[i].m_p.y = getd12(buf+18);
		m_nodes[i].m_iAttribs = geti6(buf + 48);
		int elements = geti6(buf + 36);
		int extra_records = ((elements*6) + 71) / 72 + (m_nodes[i].m_iAttribs>0);

		// linkage records
		for (int e = 0; e < extra_records; e++)
			if (!GetRecord(buf)) return false;

		if (progress_callback && (++elem % 20) == 0) progress_callback(elem * 100 / total);
	}

	// now read the areas
	for (i = 0; i < m_iAreas; i++)
	{
		if (!GetRecord(buf)) return false;

		// do some safety checking
		if (buf[0] != 'A') break;		// make sure area starts with a A
		int id = geti6(buf + 1);
		if (id != i+1) break;		// got the right area number?

		m_areas[i].m_p.x = getd12(buf+6);
		m_areas[i].m_p.y = getd12(buf+18);
		m_areas[i].m_iAttribs = geti6(buf + 48);
		int elements = geti6(buf + 36);
		int extra_records = ((elements*6) + 71) / 72 + (m_areas[i].m_iAttribs>0);

		// linkage records
		for (int e = 0; e < extra_records; e++)
			if (!GetRecord(buf)) return false;

		if (progress_callback && (++elem % 20) == 0) progress_callback(elem * 100 / total);
	}

	// now read the lines
	for (i = 0; i < m_iLines; i++)
	{
		if (!GetRecord(buf))
			return false;

		// do some safety checking
		if (buf[0] != 'L')
			break;		// make sure line starts with a L
		int id = geti6(buf + 1);
		if (id != i+1)
			break;		// got the right area number?

		m_lines[i].m_iNode1 = geti6(buf+6);
		m_lines[i].m_iNode2 = geti6(buf+12);
		m_lines[i].m_iLeftArea = geti6(buf+18);
		m_lines[i].m_iRightArea = geti6(buf+24);
		m_lines[i].m_iCoords = geti6(buf + 42);
		m_lines[i].m_iAttribs = geti6(buf + 48);

		// coordinate records
		m_lines[i].m_p.SetSize(m_lines[i].m_iCoords);
		int offset = 0;
		double x, y;
		for (int c = 0; c < m_lines[i].m_iCoords; c++)
		{
			if (c%3 == 0)
			{
				if (!GetRecord(buf))
					return false;
				offset = 0;
			}
			x = getd12(buf+offset);
			offset += 12;
			y = getd12(buf+offset);
			offset += 12;

			m_lines[i].m_p[c].x = x;
			m_lines[i].m_p[c].y = y;
		}

		// attribute records
		if (m_lines[i].m_iAttribs)
		{
			m_lines[i].m_attr.resize(m_lines[i].m_iAttribs);
			for (j = 0; j < m_lines[i].m_iAttribs; j++)
			{
				if (j%6 == 0)
				{
					if (!GetRecord(buf))
						return false;
					offset = 0;
				}
				m_lines[i].m_attr[j].m_iMajorAttr = geti6(buf+offset);
				offset += 6;
				m_lines[i].m_attr[j].m_iMinorAttr = geti6(buf+offset);
				offset += 6;
			}
		}

		if (progress_callback && (++elem % 20) == 0) progress_callback(elem * 100 / total);
	}

	// all done, close up
	fclose(m_fp);
	m_fp = NULL;
	return true;
}
Exemplo n.º 19
0
void vtDLGFile::OpenFile()
{
	m_fp = vtFileOpen(m_fname, "rb");
}
Exemplo n.º 20
0
/**
 * Loads elevation from a USGS DEM file.
 *
 * Some non-standard variations of the DEM format are supported.
 *
 * You should call SetupLocalCS() after loading if you will be doing
 * heightfield operations on this grid.
 *
 * \returns \c true if the file was successfully opened and read.
 */
bool vtElevationGrid::LoadFromDEM(const char *szFileName,
								  bool progress_callback(int), vtElevError *err)
{
	// Free buffers to prepare to receive new data
	FreeData();

	if (progress_callback != NULL) progress_callback(0);

	FILE *fp = vtFileOpen(szFileName,"rb");
	if (!fp)		// Cannot Open File
	{
		SetError(err, vtElevError::FILE_OPEN, "Couldn't open file '%s'", szFileName);
		return false;
	}

	// check for version of DEM format
	int		iRow, iColumn;
	char buffer[158];

	fseek(fp, 864, 0);
	if (fread(buffer, 144, 1, fp) != 1)
	{
		SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName);
		return false;
	}
	bool bOldFormat = (strncmp(buffer, "     1     1", 12) == 0);
	bool bNewFormat = false;
	bool bFixedLength = true;
	int  iDataStartOffset = 1024;	// set here to avoid compiler warning
	int  i, j;

	if (bOldFormat)
		iDataStartOffset = 1024;	// 1024 is record length
	else
	{
		fseek(fp, 1024, 0);		// Check for New Format
		IConvert(fp, 6, iRow);
		IConvert(fp, 6, iColumn);
		if (iRow==1 && iColumn==1)	// File OK?
		{
			bNewFormat = true;
			iDataStartOffset = 1024;
		}
		else
		{
			// might be the Non-fixed-length record format
			// Record B can start anywhere from 865 to 1023
			// Record B is identified by starting with the row/column
			//  of its first profile, "     1     1"
			fseek(fp, 865, 0);
			if (fread(buffer, 158, 1, fp) != 1)
			{
				SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName);
				fclose(fp);
				return false;
			}
			for (i = 0; i < 158-12; i++)
			{
				if (!strncmp(buffer+i, "     1     1", 12))
				{
					// Found it
					bFixedLength = false;
					iDataStartOffset = 865+i;
					break;
				}
			}
			if (i == 158-12)
			{
				// Not a DEM file
				SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName);
				fclose(fp);
				return false;
			}
		}
	}

	// Read the embedded DEM name
	char szName[41];
	fseek(fp, 0, 0);
	if (fgets(szName, 41, fp) == NULL)
		return false;
	int len = strlen(szName);	// trim trailing whitespace
	while (len > 0 && szName[len-1] == ' ')
	{
		szName[len-1] = 0;
		len--;
	}
	m_strOriginalDEMName = szName;

	fseek(fp, 156, 0);
	int iCoordSystem, iUTMZone;
	IConvert(fp, 6, iCoordSystem);
	IConvert(fp, 6, iUTMZone);

	fseek(fp, 168, 0);
	double dProjParams[15];
	for (i = 0; i < 15; i++)
	{
		if (!DConvert(fp, 24, dProjParams[i], DEBUG_DEM))
			return false;
	}

	int iDatum = EPSG_DATUM_NAD27;	// default

	// OLD format header ends at byte 864 (0x360); new format has Datum
	if (bNewFormat)
	{
		// year of data compilation
		char szDateBuffer[5];
		fseek(fp, 876, 0);		// 0x36C
		if (fread(szDateBuffer, 4, 1, fp) != 1)
			return false;
		szDateBuffer[4] = 0;

		// Horizontal datum
		// 1=North American Datum 1927 (NAD 27)
		// 2=World Geodetic System 1972 (WGS 72)
		// 3=WGS 84
		// 4=NAD 83
		// 5=Old Hawaii Datum
		// 6=Puerto Rico Datum
		fseek(fp, 890, 0);	// 0x37A
		int datum;
		IConvert(fp, 2, datum);
		VTLOG("DEM Reader: Read Datum Value %d\n", datum);
		switch (datum)
		{
			case 1: iDatum = EPSG_DATUM_NAD27; break;
			case 2: iDatum = EPSG_DATUM_WGS72; break;
			case 3: iDatum = EPSG_DATUM_WGS84; break;
			case 4:	iDatum = EPSG_DATUM_NAD83; break;
			case 5: iDatum = EPSG_DATUM_OLD_HAWAIIAN; break;
			case 6: iDatum = EPSG_DATUM_PUERTO_RICO; break;
		}
	}

	fseek(fp, 528, 0);
	int iGUnit, iVUnit;
	IConvert(fp, 6, iGUnit);
	IConvert(fp, 6, iVUnit);

	// Ground (Horizontal) Units in meters
	double	fGMeters;
	switch (iGUnit)
	{
	case 0: fGMeters = 1.0;		break;	// 0 = radians (never encountered)
	case 1: fGMeters = 0.3048;	break;	// 1 = feet
	case 2: fGMeters = 1.0;		break;	// 2 = meters
	case 3: fGMeters = 30.922;	break;	// 3 = arc-seconds
	}

	// Vertical Units in meters
	double	fVertUnits;
	switch (iVUnit)
	{
	case 1:  fVertUnits = 0.3048;  break;	// feet to meter conversion
	case 2:  fVertUnits = 1.0;	   break;	// meters == meters
	default: fVertUnits = 1.0;	   break;	// anything else, assume meters
	}

	fseek(fp, 816, 0);
	double dxdelta, dydelta, dzdelta;
	DConvert(fp, 12, dxdelta, DEBUG_DEM);	// dxdelta (unused)
	DConvert(fp, 12, dydelta, DEBUG_DEM);
	DConvert(fp, 12, dzdelta, DEBUG_DEM);

	m_bFloatMode = false;

	// Read the coordinates of the 4 corners
	VTLOG("DEM corners:\n");
	DPoint2	corners[4];			// SW, NW, NE, SE
	fseek(fp, 546, 0);
	for (i = 0; i < 4; i++)
	{
		DConvert(fp, 24, corners[i].x, DEBUG_DEM);
		DConvert(fp, 24, corners[i].y, DEBUG_DEM);
	}
	for (i = 0; i < 4; i++)
		VTLOG(" (%lf, %lf)", corners[i].x, corners[i].y);
	VTLOG("\n");

	// Set up the projection and corners
	bool bGeographic = (iCoordSystem == 0);
	if (bGeographic)
	{
		for (i = 0; i < 4; i++)
		{
			// convert arcseconds to degrees
			m_Corners[i].x = corners[i].x / 3600.0;
			m_Corners[i].y = corners[i].y / 3600.0;
		}
	}
	else
	{
		// some linear coordinate system
		for (i = 0; i < 4; i++)
			m_Corners[i] = corners[i];
	}

	// Special case.  Some old DEMs claim to be NAD27, but they are of Hawai'i,
	//  and Hawai'i has no NAD27, it is actually OHD.
	if (iDatum == EPSG_DATUM_NAD27)
	{
		DRECT Hawaii(0,0,0,0);
		if (bGeographic)
			Hawaii.SetRect(-164, 24, -152, 17);
		else if (iCoordSystem == 1)	// UTM
		{
			if (iUTMZone == 4)
				Hawaii.SetRect(240000, 2600000, 1000000, 2000000);
			else if (iUTMZone == 5)
				Hawaii.SetRect(-400000, 2600000, 400000, 2000000);
		}
		for (i = 0; i < 4; i++)
		{
			if (Hawaii.ContainsPoint(m_Corners[i]))
				iDatum = EPSG_DATUM_OLD_HAWAIIAN;
		}
	}

	bool bSuccessfulCRS = true;
	switch (iCoordSystem)
	{
	case 0:		// geographic (lat-lon)
		iUTMZone = -1;
		bSuccessfulCRS = m_proj.SetProjectionSimple(false, iUTMZone, iDatum);
		break;
	case 1:		// utm
		m_proj.SetProjectionSimple(true, iUTMZone, iDatum);
		break;
	case 3:		// Albers Conical Equal Area
		{
			// The Official DEM documentation says:
			// "Note: All angles (latitudes, longitudes, or azimuth) are
			// required in degrees, minutes, and arc seconds in the packed
			// real number format +DDDOMMOSS.SSSSS."
			// However, what i've actually seen is values like:
			//  0.420000000000000D+06' -> 420000
			// for 42 degrees, which is off by a decimal point from the DEM docs.
			// So, intepret the values with factor of 10000 to convert to degrees:

			// double semi_major = dProjParams[0];		// unused
			// double eccentricity = dProjParams[1];	// unused
			double lat_1st_std_parallel = dProjParams[2] / 10000;
			double lat_2nd_std_parallel = dProjParams[3] / 10000;
			double lon_central_meridian = dProjParams[4] / 10000;
			double lat_origin = dProjParams[5] / 10000;
			double false_easting = dProjParams[6];
			double false_northing = dProjParams[7];

			m_proj.SetGeogCSFromDatum(iDatum);
			m_proj.SetACEA(lat_1st_std_parallel, lat_2nd_std_parallel, lat_origin,
				lon_central_meridian, false_easting, false_northing);
		}
		break;
	case 2:		// State Plane (!)
	case 4:		// Lambert Conformal
	case 5:		// Mercator
	case 6:		// Polar Stereographic
	case 7:		// Polyconic
	case 8:		// Equidistant Conic Type A / B
	case 9:		// Transverse Mercator
	case 10:	// Stereographic
	case 11:	// Lambert Azimuthal Equal-Area
	case 12:	// Azimuthal Equidistant
	case 13:	// Gnomonic
	case 14:	// Orthographic
	case 15:	// General Vertical Near-Side Perspective
	case 16:	// Sinusoidal (Plate Caree)
	case 17:	// Equirectangular
	case 18:	// Miller Cylindrical
	case 19:	// Van Der Grinten I
	case 20:	// Oblique Mercator
		VTLOG("Warning!  We don't yet support DEM coordinate system %d.\n", iCoordSystem);
		break;
	}

	// We must have a functional CRS, or it will sebsequently fail
	if (!bSuccessfulCRS)
	{
		SetError(err, vtElevError::READ_CRS, "Couldn't determine CRS of DEM file");
		return false;
	}

	double dElevMin, dElevMax;
	DConvert(fp, 24, dElevMin, DEBUG_DEM);
	DConvert(fp, 24, dElevMax, DEBUG_DEM);

	fseek(fp, 852, 0);
	int iRows, iProfiles;
	IConvert(fp, 6, iRows);	// This "Rows" value will always be 1
	IConvert(fp, 6, iProfiles);
	VTLOG("DEM profiles: %d\n", iProfiles);

	m_iSize.x = iProfiles;

	// values we'll need while scanning the elevation profiles
	int		iProfileRows, iProfileCols;
	int		iElev;
	double	dLocalDatumElev, dProfileMin, dProfileMax;
	int		ygap;
	double	dMinY;
	DPoint2 start;

	if (bGeographic)
	{
		// If it's in degrees, it's flush square, so we can simply
		// derive the extents (m_EarthExtents) from the quad corners (m_Corners)
		ComputeExtentsFromCorners();
		dMinY = std::min(corners[0].y, corners[3].y);
	}
	else
	{
		VTLOG("DEM scanning to compute extents\n");
		m_EarthExtents.SetInsideOut();

		if (!bFixedLength)
			fseek(fp, iDataStartOffset, 0);
		// Need to scan over all the profiles, accumulating the TRUE
		// extents of the actual data points.
		int record = 0;
		int data_len;
		for (i = 0; i < iProfiles; i++)
		{
			if (progress_callback != NULL)
				progress_callback(i*49/iProfiles);

			if (bFixedLength)
				fseek(fp, iDataStartOffset + (record * 1024), 0);

			// We cannot use IConvert here, because there *might* be a spurious LF
			// after the number - seen in some rare files.
			if (fscanf(fp, "%d", &iRow) != 1)
			{
				SetError(err, vtElevError::READ_DATA, "Error reading DEM at profile %d of %d",
					i, iProfiles);
				return false;
			}
			IConvert(fp, 6, iColumn);
			// assert(iColumn == i+1);
			IConvert(fp, 6, iProfileRows);
			IConvert(fp, 6, iProfileCols);

			DConvert(fp, 24, start.x);
			DConvert(fp, 24, start.y);
			m_EarthExtents.GrowToContainPoint(start);
			start.y += ((iProfileRows-1) * dydelta);
			m_EarthExtents.GrowToContainPoint(start);

			if (bFixedLength)
			{
				record++;
				data_len = 144 + (iProfileRows * 6);
				while (data_len > 1020)	// max bytes in a record
				{
					data_len -= 1020;
					record++;
				}
			}
			else
			{
				DConvert(fp, 24, dLocalDatumElev);
				DConvert(fp, 24, dProfileMin);
				DConvert(fp, 24, dProfileMax);
				for (j = 0; j < iProfileRows; j++)
				{
					// We cannot use IConvert here, because there *might* be a spurious LF
					// after the number - seen in some rare files.
					if (fscanf(fp, "%d", &iElev) != 1)
						return false;
				}
			}
		}
		dMinY = m_EarthExtents.bottom;
	}
	VTLOG("DEM extents LRTB: %lf, %lf, %lf, %lf\n", m_EarthExtents.left,
		m_EarthExtents.right, m_EarthExtents.top, m_EarthExtents.bottom);

	// Compute number of rows
	double	fRows;
	if (bGeographic)
	{
		// degrees
		fRows = m_EarthExtents.Height() / dydelta * 3600.0f;
		m_iSize.y = (int)fRows + 1;	// 1 more than quad spacing
	}
	else
	{
		// some linear coordinate system
		fRows = m_EarthExtents.Height() / dydelta;
		m_iSize.y = (int)(fRows + 0.5) + 1;	// round to the nearest integer
	}

	// safety check
	if (m_iSize.y > 20000)
		return false;

	if (!AllocateGrid(err))
		return false;

	// jump to start of actual data
	fseek(fp, iDataStartOffset, 0);

	for (i = 0; i < iProfiles; i++)
	{
		if (progress_callback != NULL)
			progress_callback(50+i*49/iProfiles);

		// We cannot use IConvert here, because there *might* be a spurious LF
		// after the number - seen in some rare files.
		if (fscanf(fp, "%d", &iRow) != 1)
			return false;
		IConvert(fp, 6, iColumn);
		//assert(iColumn == i+1);

		IConvert(fp, 6, iProfileRows);
		IConvert(fp, 6, iProfileCols);

		DConvert(fp, 24, start.x);
		DConvert(fp, 24, start.y);
		DConvert(fp, 24, dLocalDatumElev);
		DConvert(fp, 24, dProfileMin);
		DConvert(fp, 24, dProfileMax);

		ygap = (int)((start.y - dMinY)/dydelta);

		for (j = ygap; j < (ygap + iProfileRows); j++)
		{
			//assert(j >=0 && j < m_iSize.y);	// useful safety check

			// We cannot use IConvert here, because there *might* be a spurious LF
			// after the number - seen in some rare files.
			if (fscanf(fp, "%d", &iElev) != 1)
				return false;
			if (iElev == -32767 || iElev == -32768)
				SetValue(i, j, INVALID_ELEVATION);
			else
			{
				// The DEM spec says:
				// "A value in this array would be multiplied by the "z" spatial
				// resolution (data element 15, record type A) and added to the
				// "Elevation of local datum for the profile" (data element 4, record
				// type B) to obtain the elevation for the point."
				SetValue(i, j, (short) iElev + (short) dLocalDatumElev);
			}
		}
	}
	fclose(fp);

	m_fVMeters = (float) (fVertUnits * dzdelta);
	ComputeHeightExtents();
	if (m_fMinHeight != dElevMin || m_fMaxHeight != dElevMax)
		VTLOG("DEM Reader: elevation extents in .dem (%.1f, %.1f) don't match data (%.1f, %.1f).\n",
		dElevMin, dElevMax, m_fMinHeight, m_fMaxHeight);

	return true;
}
Exemplo n.º 21
0
int vtUnzip::Extract(bool bFullPath, bool bOverwrite, const char *lpszDst,
					 bool progress_callback(int))
{
	int iCount = 0;
	int iTotal = GetGlobalCount();

	bool bOK = true;
	for (bool bContinue = GoToFirstFile(); bContinue; bContinue = GoToNextFile())
	{
		char szFileName[MAX_PATH];
		unz_file_info info;
		bOK = GetCurrentFileInfo(&info, szFileName, MAX_PATH);
		if (!bOK)
			break;

		vtString src_filename = szFileName;

		const char *short_fname = (const char *)src_filename;
		for (const char *p = short_fname;
			(*p) != '\0';
			p++)
		{
			if (((*p)=='/') || ((*p)=='\\'))
			{
				short_fname = p+1;
			}
		}
		vtString short_filename = short_fname;

		if ((*short_filename)=='\0')
		{
			if (bFullPath)
			{
				VTLOG("creating directory: %s\n", (const char *)src_filename);
				vtCreateDir(src_filename);
			}
		}
		else
		{
			bOK = OpenCurrentFile();
			if (bOK)
			{
				vtString write_filename;
				write_filename = vtString(lpszDst) + (bFullPath ? src_filename : short_filename);

				vtString strResult;

				VTLOG("Extracting %s ...", (const char *) write_filename);
				if (ExtractAccept(write_filename, bOverwrite))
				{
					FILE* file = vtFileOpen(write_filename, "wb");

					bool bWrite = (file != NULL);
					if (bWrite)
					{
						char buf[4096];
						bWrite = ExtractCurrentFile(file, buf, 4096);
						fclose(file);
					}
					if (bWrite)
					{
						vtUnzip::change_file_date(write_filename,info.dosDate, info.tmu_date);
						iCount++;
						if (progress_callback != NULL)
						{
							progress_callback(iCount * 99 / iTotal);
						}
					}
					else
					{
						m_error_count++;
						OnError(write_filename);
					}
					strResult = bWrite ? "ok" : "failed";
				}
				else
				{
					strResult = "skipped";
				}
				VTLOG(" %s\n", (const char *) strResult);
				CloseCurrentFile();
			}
		}
	}
	if (bOK)
		return iCount;
	else
		return -1;
}
Exemplo n.º 22
0
/**
 * Writes the grid to a BT (Binary Terrain) file.
 * The current BT format version (1.3) is written.
 *
 * \param szFileName		The file name to write to.
 * \param progress_callback If supplied, this function will be called back
 *				with a value of 0 to 100 as the operation progresses.
 * \param bGZip			If true, the data will be compressed with gzip.
 *				If true, you should Use a filename ending with ".gz".
 */
bool vtElevationGrid::SaveToBT(const char *szFileName,
							   bool progress_callback(int), bool bGZip)
{
	int w = m_iColumns;
	int h = m_iRows;
	short zone = (short) m_proj.GetUTMZone();
	short datum = (short) m_proj.GetDatum();
	short isfloat = (short) IsFloatMode();
	short external = 1;		// always true: we always write an external .prj file

	LinearUnits units = m_proj.GetUnits();
	int hunits = (int) units;

	// Latest header, version 1.2
	short datasize = m_bFloatMode ? 4 : 2;
	DataType datatype = m_bFloatMode ? DT_FLOAT : DT_SHORT;

	if (bGZip == false)
	{
		// Use conventional IO
		FILE *fp = vtFileOpen(szFileName, "wb");
		if (!fp)
			return false;

		fwrite("binterr1.3", 10, 1, fp);
		FWrite(&w, DT_INT, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&h, DT_INT, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&datasize, DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&isfloat, DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&hunits,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);	// Horizontal Units (0, 1, 2, 3)
		FWrite(&zone,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);		// UTM zone
		FWrite(&datum,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);	// Datum

		// coordinate extents
		FWrite(&m_EarthExtents.left,	DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&m_EarthExtents.right,	DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&m_EarthExtents.bottom,	DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		FWrite(&m_EarthExtents.top,		DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);

		FWrite(&external, DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);		// External projection specification
		FWrite(&m_fVMeters, DT_FLOAT, 1, fp, BO_LITTLE_ENDIAN);	// Vertical scale factor (meters/units)

		// now write the data: always starts at offset 256
		fseek(fp, 256, SEEK_SET);

#if 0
		// slow way, one heixel at a time
		for (int i = 0; i < w; i++)
		{
			if (progress_callback != NULL) progress_callback(i * 100 / w);
			for (j = 0; j < h; j++)
			{
				if (m_bFloatMode) {
					fvalue = GetFValue(i, j);
					FWrite(&fvalue, datatype, 1, fp, BO_LITTLE_ENDIAN);
				} else {
					svalue = GetValue(i, j);
					FWrite(&svalue, datatype, 1, fp, BO_LITTLE_ENDIAN);
				}
			}
		}
#else
		// fast way, with the assumption that the data is stored column-first in memory
		if (m_bFloatMode)
		{
			for (int i = 0; i < w; i++)
			{
				if (progress_callback != NULL)
				{
					if (progress_callback(i * 100 / w))
					{ fclose(fp); return false; }
				}
				FWrite(m_pFData + (i * m_iRows), DT_FLOAT, m_iRows, fp, BO_LITTLE_ENDIAN);
			}
		}
		else
		{
			for (int i = 0; i < w; i++)
			{
				if (progress_callback != NULL)
				{
					if (progress_callback(i * 100 / w))
					{ fclose(fp); return false; }
				}
				FWrite(m_pData + (i * m_iRows), DT_SHORT, m_iRows, fp, BO_LITTLE_ENDIAN);
			}
		}
#endif
		fclose(fp);
	}
	else
	{
		// Use GZip IO
		gzFile fp = vtGZOpen(szFileName, "wb");
		if (!fp)
			return false;

		gzwrite(fp, (void *)"binterr1.3", 10);
		GZFWrite(&w, DT_INT, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&h, DT_INT, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&datasize,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&isfloat,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&hunits,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);		// Horizontal Units (0, 1, 2, 3)
		GZFWrite(&zone,		DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);		// UTM zone
		GZFWrite(&datum,	DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);		// Datum

		// coordinate extents
		GZFWrite(&m_EarthExtents.left,		DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&m_EarthExtents.right,		DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&m_EarthExtents.bottom,	DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);
		GZFWrite(&m_EarthExtents.top,		DT_DOUBLE, 1, fp, BO_LITTLE_ENDIAN);

		GZFWrite(&external,		DT_SHORT, 1, fp, BO_LITTLE_ENDIAN);	// External projection specification
		GZFWrite(&m_fVMeters,	DT_FLOAT, 1, fp, BO_LITTLE_ENDIAN);	// Vertical scale factor (meters/units)

		// now write the data: always starts at offset 256
		gzseek(fp, 256, SEEK_SET);

		// fast way, with the assumption that the data is stored column-first in memory
		if (m_bFloatMode)
		{
			for (int i = 0; i < w; i++)
			{
				if (progress_callback != NULL)
				{
					if (progress_callback(i * 100 / w))
					{ gzclose(fp); return false; }
				}
				GZFWrite(m_pFData + (i * m_iRows), DT_FLOAT, m_iRows, fp, BO_LITTLE_ENDIAN);
			}
		}
		else
		{
			for (int i = 0; i < w; i++)
			{
				if (progress_callback != NULL)
				{
					if (progress_callback(i * 100 / w))
					{ gzclose(fp); return false; }
				}
				GZFWrite(m_pData + (i * m_iRows), DT_SHORT, m_iRows, fp, BO_LITTLE_ENDIAN);
			}
		}
		gzclose(fp);
	}

	if (external)
	{
		// Write external projection file (.prj)
		char prj_name[256];
		strcpy(prj_name, szFileName);
		int len = strlen(prj_name);
		if (bGZip)
			strcpy(prj_name + len - 6, ".prj"); // overwrite the .bt.gz
		else
			strcpy(prj_name + len - 3, ".prj"); // overwrite the .bt
		m_proj.WriteProjFile(prj_name);
	}

	return true;
}
Exemplo n.º 23
0
bool vtImage::_ReadPNG(const char *filename)
{
	FILE *fp = NULL;

	uchar header[8];
	png_structp png;
	png_infop   info;
	png_infop   endinfo;
	png_bytep  *row_p;

	png_uint_32 width, height;
	int depth, color;

	png_uint_32 i;
	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png)
	{
		// We compiled against the headers of one version of libpng, but
		// linked against the libraries from another version.  If you get
		// this, fix the paths in your development environment.
		return false;
	}
	info = png_create_info_struct(png);
	endinfo = png_create_info_struct(png);

	fp = vtFileOpen(filename, "rb");
	if (fp && fread(header, 1, 8, fp) && png_check_sig(header, 8))
		png_init_io(png, fp);
	else
	{
		png_destroy_read_struct(&png, &info, &endinfo);
		return false;
	}
	png_set_sig_bytes(png, 8);

	png_read_info(png, info);
	png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);

	if (color == PNG_COLOR_TYPE_GRAY || color == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png);

	// never strip alpha
//	{
//		png_set_strip_alpha(png);
//		color &= ~PNG_COLOR_MASK_ALPHA;
//	}

	// Always expand paletted images
	if (color == PNG_COLOR_TYPE_PALETTE)
		png_set_expand(png);

	/*--GAMMA--*/
//	checkForGammaEnv();
	double screenGamma = 2.2 / 1.0;
#if 0
	// Getting the gamma from the PNG file is disabled here, since
	// PhotoShop writes bizarre gamma values like .227 (PhotoShop 5.0)
	// or .45 (newer versions)
	double	fileGamma;
	if (png_get_gAMA(png, info, &fileGamma))
		png_set_gamma(png, screenGamma, fileGamma);
	else
#endif
		png_set_gamma(png, screenGamma, 1.0/2.2);

	png_read_update_info(png, info);

	m_pPngData = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
	row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);

	bool StandardOrientation = true;
	for (i = 0; i < height; i++) {
		if (StandardOrientation)
			row_p[height - 1 - i] = &m_pPngData[png_get_rowbytes(png, info)*i];
		else
			row_p[i] = &m_pPngData[png_get_rowbytes(png, info)*i];
	}

	png_read_image(png, row_p);
	free(row_p);

	int iBitCount;

	switch (color)
	{
		case PNG_COLOR_TYPE_GRAY:
		case PNG_COLOR_TYPE_RGB:
		case PNG_COLOR_TYPE_PALETTE:
			iBitCount = 24;
			break;

		case PNG_COLOR_TYPE_GRAY_ALPHA:
		case PNG_COLOR_TYPE_RGB_ALPHA:
			iBitCount = 32;
			break;

		default:
			return false;
	}

	png_read_end(png, endinfo);
	png_destroy_read_struct(&png, &info, &endinfo);

	// Don't free the data, we're going to pass it to OSG
//	free(m_pPngData);

	if (fp)
		fclose(fp);

	int pixelFormat;
	uint internalFormat;

	if (iBitCount == 24)
		pixelFormat = GL_RGB;
	else if (iBitCount == 32)
		pixelFormat = GL_RGBA;

	if (m_internalformat == -1)
		internalFormat = pixelFormat;	// use default
	else
		internalFormat = m_internalformat;	// use specific

	setImage(width, height, 1,
	   internalFormat,		// int internalFormat,
	   pixelFormat,			// uint pixelFormat
	   GL_UNSIGNED_BYTE,	// uint dataType
	   m_pPngData,
	   osg::Image::USE_MALLOC_FREE);

	return true;
}
Exemplo n.º 24
0
bool vtTin::ReadADF(const char *fname, bool progress_callback(int))
{
	const vtString tnxy_name = fname;
	if (tnxy_name.Right(6) != "xy.adf")
		return false;

	vtString base = tnxy_name.Left(tnxy_name.GetLength()-6);
	vtString tnz_name = base + "z.adf";
	vtString tnod_name = base + "od.adf";

	FILE *fp1 = vtFileOpen(tnxy_name, "rb");
	FILE *fp2 = vtFileOpen(tnz_name, "rb");
	FILE *fp3 = vtFileOpen(tnod_name, "rb");
	if (!fp1 || !fp2 || !fp3)
		return false;

	fseek(fp1, 0, SEEK_END);
	const int length_xy = ftell(fp1);
	rewind(fp1);	// go back again
	uint num_points = length_xy / 16;	// X and Y, each 8 byte doubles

	fseek(fp2, 0, SEEK_END);
	const int length_z = ftell(fp2);
	rewind(fp2);	// go back again
	uint num_heights = length_z / 4;		// Z is a 4 byte float

	DPoint2 p;
	float z;
	for (uint i = 0; i < num_points; i++)
	{
		if ((i%200) == 0 && progress_callback != NULL)
			progress_callback(i * 40 / num_points);

		FRead(&p.x, DT_DOUBLE, 2, fp1, BO_BIG_ENDIAN, BO_LITTLE_ENDIAN);
		FRead(&z, DT_FLOAT, 1, fp2, BO_BIG_ENDIAN, BO_LITTLE_ENDIAN);
		AddVert(p, z);
	}

	fseek(fp3, 0, SEEK_END);
	const int length_od = ftell(fp3);
	rewind(fp3);	// go back again
	const uint num_faces = length_od / 12;		// A B C as 4-byte ints

	int v[3];
	for (uint i = 0; i < num_faces; i++)
	{
		if ((i%200) == 0 && progress_callback != NULL)
			progress_callback(40 + i * 40 / num_faces);

		FRead(v, DT_INT, 3, fp3, BO_BIG_ENDIAN, BO_LITTLE_ENDIAN);
		AddTri(v[0]-1, v[1]-1, v[2]-1);
	}

	fclose(fp1);
	fclose(fp2);
	fclose(fp3);

	// Cleanup: the ESRI TIN contains four "boundary" point far outside the
	//  extents (directly North, South, East, and West).  We should ignore
	//  those four points and the triangles connected to them.
	// It seems we can assume the four 'extra' vertices are the first four.
	m_vert.RemoveAt(0, 4);
	m_z.erase(m_z.begin(), m_z.begin() + 4);
	m_vert_normal.RemoveAt(0, 4);

	// Re-index the triangles
	uint total = m_tri.size()/3;
	for (uint i = 0; i < total; i++)
	{
		if ((i%200) == 0 && progress_callback != NULL)
			progress_callback(80 + i * 20 / total);

		// Remove any triangles which referenced this vertex
		if (m_tri[i*3 + 0] < 4 ||
			m_tri[i*3 + 1] < 4 ||
			m_tri[i*3 + 2] < 4)
		{
			m_tri.erase(m_tri.begin() + i*3, m_tri.begin() + i*3 + 3);
			i--;
			total--;
			continue;
		}
	}
	// For all other triangles, adjust the indices to reflect the removal
	for (uint i = 0; i < m_tri.size(); i++)
		m_tri[i] = m_tri[i] - 4;

	// Test each triangle for clockwisdom, fix if needed
	CleanupClockwisdom();

	ComputeExtents();

	return true;
}
Exemplo n.º 25
0
/**
 * Write the TIN to a VRML (.wrl) file as an IndexedFaceSet.  Note that we
 * write X and Y as geographic coordinates, but VRML only supports
 * single-precision floating point values, so it may lose some precision.
 */
bool vtTin::WriteWRL(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	fprintf(fp, "#VRML V2.0 utf8\n");
	fprintf(fp, "\n");
	fprintf(fp, "WorldInfo\n");
	fprintf(fp, "  {\n");
	fprintf(fp, "  info\n");
	fprintf(fp, "    [\n");
	fprintf(fp, "    \"Generated by VTBuilder\"\n");
	fprintf(fp, "    ]\n");
	fprintf(fp, "  title \"TIN VRML Model\"\n");
	fprintf(fp, "  }\n");
	fprintf(fp, "\n");
	fprintf(fp, "# TIN---------\n");
	fprintf(fp, "Transform\n");
	fprintf(fp, "  {\n");
	fprintf(fp, "  children\n");
	fprintf(fp, "    [\n");
	fprintf(fp, "    Shape\n");
	fprintf(fp, "      {\n");
	fprintf(fp, "      appearance Appearance\n");
	fprintf(fp, "	{\n");
	fprintf(fp, "	material Material\n");
	fprintf(fp, "	  {\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "	texture ImageTexture\n");
	fprintf(fp, "	  {\n");
	fprintf(fp, "	  url\n");
	fprintf(fp, "	    [\n");
	fprintf(fp, "	    \"OrtoImage.jpg\"\n");
	fprintf(fp, "	    ]\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "	}\n");
	fprintf(fp, "      geometry      IndexedFaceSet {\n");
	fprintf(fp, "              ccw FALSE\n");
	fprintf(fp, "              solid FALSE\n");
	fprintf(fp, "              creaseAngle 1.396263\n");
	fprintf(fp, "coord DEF Kxzy Coordinate {\n");
	fprintf(fp, "                                     point [\n");

	int i, count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// write verts
	//	fprintf(fp, "VERT %d\n", verts);
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "	    ]\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "      	coordIndex \n");
	fprintf(fp, "                  [\n");

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is  triangle definition (zero based)  A B C -1...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d -1\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "				  ]\n");
	fprintf(fp, "				}\n");
	fprintf(fp, "			      }\n");
	fprintf(fp, "			    ]\n");
	fprintf(fp, "			  }\n");
	fclose(fp);
	return true;
}
Exemplo n.º 26
0
/**
 * Write the TIN to a Collada (.dae) file.  Note that we write X and Y as
 * geographic coordinates, but DAE only supports single-precision floating
 * point values, so it may lose some precision.
 */
bool vtTin::WriteDAE(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	// first line is file identifier
	fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
	fprintf(fp, "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">\n");
	fprintf(fp, "  <asset>\n");
	fprintf(fp, "    <contributor>\n");
	fprintf(fp, "      <authoring_tool>VTBuilder</authoring_tool>\n");
	fprintf(fp, "    </contributor>\n");
//	fprintf(fp, "    <created>2012-01-09T14:26:45Z</created>\n");
//	fprintf(fp, "    <modified>2012-01-09T14:26:45Z</modified>\n");
//	fprintf(fp, "    <unit meter=\"0.02539999969303608\" name=\"inch\" />\n");
	fprintf(fp, "    <up_axis>Z_UP</up_axis>\n");
	fprintf(fp, "  </asset>\n");
	fprintf(fp, "  <library_visual_scenes>\n");
	fprintf(fp, "    <visual_scene id=\"ID1\">\n");
	fprintf(fp, "      <node name=\"VTBuilder\">\n");
	fprintf(fp, "        <node id=\"ID2\" name=\"Earth_Terrain\">\n");
	fprintf(fp, "          <matrix>1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>\n");
	fprintf(fp, "          <instance_geometry url=\"#ID3\">\n");
	fprintf(fp, "            <bind_material>\n");
	fprintf(fp, "              <technique_common>\n");
	fprintf(fp, "                <instance_material symbol=\"Material2\" target=\"#ID4\">\n");
	fprintf(fp, "                  <bind_vertex_input semantic=\"UVSET0\" input_semantic=\"TEXCOORD\" input_set=\"0\" />\n");
	fprintf(fp, "                </instance_material>\n");
	fprintf(fp, "              </technique_common>\n");
	fprintf(fp, "            </bind_material>\n");
	fprintf(fp, "          </instance_geometry>\n");
	fprintf(fp, "        </node>\n");
	fprintf(fp, "      </node>\n");
	fprintf(fp, "    </visual_scene>\n");
	fprintf(fp, "  </library_visual_scenes>\n");
	fprintf(fp, "  <library_geometries>\n");
	fprintf(fp, "    <geometry id=\"ID3\">\n");
	fprintf(fp, "      <mesh>\n");
	fprintf(fp, "        <source id=\"ID6\">\n");

	int count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// Here are:   Count   and   Coordinates X Y Z...
	fprintf(fp, "          <float_array id=\"ID10\" count=\"%d\">\n",verts);

	// write verts
	for (int i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "          </float_array>\n");

	fprintf(fp, "          <technique_common>\n");
	fprintf(fp, "            <accessor count=\"222\" source=\"#ID10\" stride=\"3\">\n");
	fprintf(fp, "              <param name=\"X\" type=\"float\" />\n");
	fprintf(fp, "              <param name=\"Y\" type=\"float\" />\n");
	fprintf(fp, "              <param name=\"Z\" type=\"float\" />\n");
	fprintf(fp, "            </accessor>\n");
	fprintf(fp, "          </technique_common>\n");
	fprintf(fp, "        </source>\n");
	fprintf(fp, "\n");
	fprintf(fp, "        <source id=\"ID8\">\n");
	fprintf(fp, "          <Name_array id=\"ID12\" count=\"0\" />\n");
	fprintf(fp, "          <technique_common>\n");
	fprintf(fp, "            <accessor count=\"0\" source=\"#ID12\" stride=\"1\">\n");
	fprintf(fp, "              <param name=\"skp_material\" type=\"Name\" />\n");
	fprintf(fp, "            </accessor>\n");
	fprintf(fp, "          </technique_common>\n");
	fprintf(fp, "        </source>\n");
	fprintf(fp, "        <vertices id=\"ID9\">\n");
	fprintf(fp, "          <input semantic=\"POSITION\" source=\"#ID6\" />\n");
	fprintf(fp, "          <input semantic=\"NORMAL\" source=\"#ID7\" />\n");
	fprintf(fp, "        </vertices>\n");

	// Here is triangles Count
	fprintf(fp, "        <triangles count=\"%d\" material=\"Material2\">\n", tris);
	fprintf(fp, "          <input offset=\"0\" semantic=\"VERTEX\" source=\"#ID9\" />\n");
	fprintf(fp, "          <p>\n");

	// write tris
	//	fprintf(fp, "TRI %d\n", tris);
	for (int i = 0; i < tris; i++)
	{
		// Here is     triangle definition (zero based)  A B C ...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "</p>\n");

	fprintf(fp, "        </triangles>\n");
	fprintf(fp, "      </mesh>\n");
	fprintf(fp, "    </geometry>\n");
	fprintf(fp, "  </library_geometries>\n");
	fprintf(fp, "  <library_materials>\n");
	fprintf(fp, "    <material id=\"ID4\" name=\"Google_Earth_Snapshot\">\n");
	fprintf(fp, "      <instance_effect url=\"#ID5\" />\n");
	fprintf(fp, "    </material>\n");
	fprintf(fp, "  </library_materials>\n");
	fprintf(fp, "  <library_effects>\n");
	fprintf(fp, "    <effect id=\"ID5\">\n");
	fprintf(fp, "      <profile_COMMON>\n");
	fprintf(fp, "        <technique sid=\"COMMON\">\n");
	fprintf(fp, "          <lambert>\n");
	fprintf(fp, "            <diffuse>\n");

	// Here is the color definition of the surface
	fprintf(fp, "              <color>0.3411764705882353 0.392156862745098 0.3411764705882353 1</color>\n");

	fprintf(fp, "            </diffuse>\n");
	fprintf(fp, "          </lambert>\n");
	fprintf(fp, "        </technique>\n");
	fprintf(fp, "      </profile_COMMON>\n");
	fprintf(fp, "    </effect>\n");
	fprintf(fp, "  </library_effects>\n");
	fprintf(fp, "  <scene>\n");
	fprintf(fp, "    <instance_visual_scene url=\"#ID1\" />\n");
	fprintf(fp, "  </scene>\n");
	fprintf(fp, "</COLLADA>\n");

	fclose(fp);
	return true;
}
Exemplo n.º 27
0
/**
 * Write the TIN to the Aquaveo GMS format.
 */
bool vtTin::ReadGMS(const char *fname, bool progress_callback(int))
{
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	char buf[256];
	vtString tin_name;
	int material_id;
	int num_points;

	// first line is file identifier
	if (fgets(buf, 256, fp) == NULL)
		return false;

	if (strncmp(buf, "TIN", 3) != 0)
		return false;

	while (1)
	{
		if (fgets(buf, 256, fp) == NULL)
			break;

		// trim trailing EOL characters
		vtString vstr = buf;
		vstr.Remove('\r');
		vstr.Remove('\n');
		const char *str = (const char *)vstr;

		if (!strncmp(str, "BEGT", 4))	// beginning of TIN block
			continue;

		if (!strncmp(str, "ID", 2))	// material ID
		{
			sscanf(str, "ID %d", &material_id);
		}
		else if (!strncmp(str, "MAT", 3))	// material ID
		{
			sscanf(str, "MAT %d", &material_id);
		}
		else if (!strncmp(str, "TCOL", 4))	// material ID
		{
			sscanf(str, "TCOL %d", &material_id);
		}
		else if (!strncmp(str, "TNAM", 4))	// TIN name
		{
			tin_name = str + 5;
		}
		else if (!strncmp(str, "VERT", 4))	// Beginning of vertices
		{
			sscanf(buf, "VERT %d\n", &num_points);
			DPoint2 p;
			float z;
			int optional;
			for (int i = 0; i < num_points; i++)
			{
				if (fgets(buf, 256, fp) == NULL)
					break;

				// First three are X, Y, Z.  Optional fourth is "ID" or "locked".
				sscanf(buf, "%lf %lf %f %d", &p.x, &p.y, &z, &optional);
#if 0
				// Some files have Y/-Z flipped (but they are non-standard)
				double temp = p.y; p.y = -z; z = temp;
#endif

				AddVert(p, z);

				if ((i%200) == 0 && progress_callback != NULL)
				{
					if (progress_callback(i * 49 / num_points))
					{
						fclose(fp);
						return false;	// user cancelled
					}
				}
			}
		}
		else if (!strncmp(str, "TRI", 3))	// Beginning of triangles
		{
			int num_faces;
			sscanf(str, "TRI %d\n", &num_faces);
			int v[3];
			for (int i = 0; i < num_faces; i++)
			{
				fscanf(fp, "%d %d %d\n", v, v+2, v+1);
				// the indices in the file are 1-based, so subtract 1
				AddTri(v[0]-1, v[1]-1, v[2]-1);

				if ((i%200) == 0 && progress_callback != NULL)
				{
					if (progress_callback(49 + i * 50 / num_faces))
					{
						fclose(fp);
						return false;	// user cancelled
					}
				}
			}
		}
	}
	fclose(fp);
	ComputeExtents();
	return true;
}
Exemplo n.º 28
0
bool vtElevLayer::ImportFromFile(const wxString &strFileName,
	bool progress_callback(int), vtElevError *err)
{
	// Avoid trouble with '.' and ',' in Europe - all the file readers assume
	//  the default "C" locale.
	ScopedLocale normal_numbers(LC_NUMERIC, "C");

	wxString strExt = strFileName.AfterLast('.');
	vtString fname = (const char *) strFileName.mb_str(wxConvUTF8);

	VTLOG("ImportFromFile '%s'\n", (const char *) fname);

	if (!strExt.CmpNoCase(_T("gz")))
	{
		// ignore .gz, look at extension under it
		wxString dropped = strFileName.Left(strFileName.Len()-3);
		strExt = dropped.AfterLast('.');
	}

	if (!strExt.CmpNoCase(_T("bz2")))
	{
		// ignore .bz2, look at extension under it
		wxString dropped = strFileName.Left(strFileName.Len()-4);
		strExt = dropped.AfterLast('.');
	}

	// The first character in the file is useful for telling which format
	// the file really is.
	FILE *fp = vtFileOpen(fname, "rb");
	char first = fgetc(fp);
	fclose(fp);

	bool success = false;

	if (!strExt.CmpNoCase(_T("dxf")))
	{
		m_pTin = new vtTin2d;
		success = m_pTin->ReadDXF(fname, progress_callback);
	}
	else
	if (!strFileName.Right(6).CmpNoCase(_T("xy.adf")))
	{
		m_pTin = new vtTin2d;
		success = m_pTin->ReadADF(fname, progress_callback);
	}
	else
	if (!strFileName.Right(4).CmpNoCase(_T(".tin")))
	{
		m_pTin = new vtTin2d;
		success = m_pTin->ReadGMS(fname, progress_callback);
	}
	else
	if (!strFileName.Right(4).CmpNoCase(_T(".ply")))
	{
		m_pTin = new vtTin2d;
		success = m_pTin->ReadPLY(fname, progress_callback);
	}
	else
	{
		if (m_pGrid == NULL)
			m_pGrid = new vtElevationGrid;
	}

	if (!strExt.CmpNoCase(_T("3tx")))
	{
		success = m_pGrid->LoadFrom3TX(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("dem")))
	{
		// If there is a .hdr file in the same place, it is most likely
		//  a GTOPO30/SRTM30 file
		vtString hdr_fname = ChangeFileExtension(fname, ".hdr");
		if (vtFileExists(hdr_fname))
			success = m_pGrid->LoadFromGTOPO30(hdr_fname, progress_callback);
		else
		{
			if (first == '*')
				success = m_pGrid->LoadFromMicroDEM(fname, progress_callback);
			else
				success = m_pGrid->LoadFromDEM(fname, progress_callback, err);
		}
	}
	else if (!strExt.CmpNoCase(_T("asc")))
	{
		success = m_pGrid->LoadFromASC(fname, progress_callback);
		// vtElevationGrid does have its own ASC reader, but use GDAL instead
//		success = m_pGrid->LoadWithGDAL(strFileName.mb_str(wxConvUTF8), progress_callback, err);
	}
	else if (!strExt.CmpNoCase(_T("bil")))
	{
		success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
	}
	else if (!strExt.CmpNoCase(_T("mem")))
	{
		success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
	}
	else if (!strExt.CmpNoCase(_T("ter")))
	{
		success = m_pGrid->LoadFromTerragen(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("cdf")))
	{
		success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
	}
	else if (!strExt.CmpNoCase(_T("hdr")))
	{
		success = m_pGrid->LoadFromGTOPO30(fname, progress_callback);
		if (!success)
			success = m_pGrid->LoadFromGLOBE(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("dte")) ||
			!strExt.CmpNoCase(_T("dt0")) ||
			!strExt.CmpNoCase(_T("dt1")) ||
			!strExt.CmpNoCase(_T("dt2")))
	{
		success = m_pGrid->LoadFromDTED(fname, progress_callback);
	}
	else if (!strExt.Left(3).CmpNoCase(_T("pgm")))
	{
		success = m_pGrid->LoadFromPGM(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("grd")))
	{
		// might by CDF, might be Surfer GRD
		if (first == 'D')
		{
			VTLOG("First character is 'D', attempting load as a Surfer Grid file.\n");
			success = m_pGrid->LoadFromGRD(fname, progress_callback);
		}
		else
		{
			VTLOG("First character is not 'D', attempting load as a netCDF file.\n");
			success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
		}
		if (!success)
		{
			VTLOG("Didn't load successfully, attempting load with GDAL.\n");
			// Might be 'Arc Binary Grid', try GDAL
			success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
		}
	}
	else if (!strFileName.Right(8).CmpNoCase(_T("catd.ddf")) ||
			!strExt.Left(3).CmpNoCase(_T("tif")) ||
			!strExt.Left(3).CmpNoCase(_T("png")) ||
			!strExt.Left(3).CmpNoCase(_T("img")) ||
			!strExt.CmpNoCase(_T("adf")))
	{
		if (m_pGrid)
			success = m_pGrid->LoadWithGDAL(fname, progress_callback, err);
	}
	else if (!strExt.CmpNoCase(_T("raw")))
	{
		RawDlg dlg(NULL, -1, _("Raw Elevation File"));

		dlg.m_iBytes = 2;
		dlg.m_iWidth = 100;
		dlg.m_iHeight = 100;
		dlg.m_fVUnits = 1.0f;
		dlg.m_fSpacing = 30.0f;
		dlg.m_bBigEndian = false;
		dlg.m_extents.SetToZero();
		g_bld->GetProjection(dlg.m_original);

		if (dlg.ShowModal() == wxID_OK)
		{
			success = m_pGrid->LoadFromRAW(fname, dlg.m_iWidth,
					dlg.m_iHeight, dlg.m_iBytes, dlg.m_fVUnits, dlg.m_bBigEndian,
					progress_callback);
		}
		if (success)
		{
			m_pGrid->SetEarthExtents(dlg.m_extents);
			m_pGrid->SetProjection(dlg.m_proj);
		}
	}
	else if (!strExt.CmpNoCase(_T("ntf")))
	{
		success = m_pGrid->LoadFromNTF5(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("txt")) ||
		!strExt.CmpNoCase(_T("xyz")))
	{
		success = m_pGrid->LoadFromXYZ(fname, progress_callback);
	}
	else if (!strExt.CmpNoCase(_T("hgt")))
	{
		success = m_pGrid->LoadFromHGT(fname, progress_callback);
	}
	else if (!strExt.Left(2).CmpNoCase(_T("db")))
	{
		success = ImportFromDB(fname, progress_callback);
	}
	if (!success)
		return false;

	vtProjection *pProj;
	if (m_pGrid)
		pProj = &m_pGrid->GetProjection();
	else
		pProj = &m_pTin->m_proj;

	// We should ask for a CRS before asking for extents
	if (!g_bld->ConfirmValidCRS(pProj))
	{
		if (err)
		{
			err->type = vtElevError::CANCELLED;
			err->message = "Cancelled";
		}
		return false;
	}

	if (m_pGrid != NULL)
	{
		if (m_pGrid->GetEarthExtents().IsEmpty())
		{
			// No extents.
			wxString msg = _("File lacks geographic location (extents). Would you like to specify extents?\n Yes - specify extents\n No - use some default values\n");
			int res = wxMessageBox(msg, _("Elevation Import"), wxYES_NO | wxCANCEL);
			if (res == wxYES)
			{
				DRECT ext;
				ext.SetToZero();
				ExtentDlg dlg(NULL, -1, _("Elevation Grid Extents"));
				dlg.SetArea(ext, (pProj->IsGeographic() != 0));
				if (dlg.ShowModal() == wxID_OK)
					m_pGrid->SetEarthExtents(dlg.m_area);
				else
					return false;
			}
			if (res == wxNO)
			{
				// Just make up some fake extents, assuming a regular even grid
				int xsize, ysize;
				m_pGrid->GetDimensions(xsize, ysize);

				DRECT ext;
				ext.left = ext.bottom = 0;
				if (pProj->IsGeographic())
				{
					ext.right = xsize * (1.0/3600);	// arc second
					ext.top = ysize * (1.0/3600);
				}
				else
				{
					ext.right = xsize * 10;	// 10 linear units (meters, feet..)
					ext.top = ysize * 10;
				}
				m_pGrid->SetEarthExtents(ext);
			}
			if (res == wxCANCEL)
			{
				if (err)
				{
					err->type = vtElevError::CANCELLED;
					err->message = "Cancelled";
				}
				return false;
			}
		}
		m_pGrid->SetupLocalCS(1.0f);
	}
	return true;
}
Exemplo n.º 29
0
void vtLog::StartLog(const char *fname)
{
	m_log = vtFileOpen(fname, "wb");
}
Exemplo n.º 30
0
bool vtTin::ReadPLY(const char *fname, bool progress_callback(int))
{
	FILE *fp = vtFileOpen(fname, "rb");
	if (!fp)
		return false;

	VTLOG("ReadPLY '%s'\n", fname);

	char buf[256];
	int material_id;
	int num_points;
	int num_faces;

	// first line is file identifier
	if (fgets(buf, 256, fp) == NULL)
		return false;

	if (strncmp(buf, "ply", 3) != 0)
		return false;

	while (fgets(buf, 256, fp) != NULL)
	{
		// trim trailing EOL characters
		vtString vstr = buf;
		vstr.Remove('\r');
		vstr.Remove('\n');
		const char *str = (const char *)vstr;

		if (!strncmp(str, "format", 6))	// beginning of TIN block
			continue;

		if (!strncmp(str, "ID", 2))	// material ID
		{
			sscanf(str, "ID %d", &material_id);
		}
		else if (!strncmp(str, "MAT", 3))	// material ID
		{
			sscanf(str, "MAT %d", &material_id);
		}
		else if (!strncmp(str, "TCOL", 4))	// material ID
		{
			sscanf(str, "TCOL %d", &material_id);
		}
 		else if (!strncmp(str, "element vertex", 14))	// Number of vertices
		{
			sscanf(buf, "element vertex %d\n", &num_points);
		}
 		else if (!strncmp(str, "element face", 12))	// Number of triangles
		{
			sscanf(buf, "element face %d\n", &num_faces);
		}
		else if (!strncmp(str, "end_header", 10))
		{
			DPoint2 p;
			float z;
			int optional;

			VTLOG("ReadPLY num_points %d\n", num_points);

			for (int i = 0; i < num_points; i++)
			{
				if (fgets(buf, 256, fp) == NULL)
					break;

				// First three are X, Y, Z.  Optional fourth is "ID" or "locked".
				sscanf(buf, "%lf %lf %f %d", &p.x, &p.y, &z, &optional);
#if 0
				// Some files have Y/-Z flipped (but they are non-standard)
				double temp = p.y; p.y = -z; z = temp;
#endif
				AddVert(p, z);

				if ((i%200) == 0 && progress_callback != NULL)
				{
					if (progress_callback(i * 49 / num_points))
					{
						fclose(fp);
						return false;	// user cancelled
					}
				}
			}

			// Then read the triangles
			VTLOG("ReadPLY num_faces %d\n", num_faces);

			int inu, a, b, c;
			for (int i = 0; i < num_faces; i++)
			{
				if (fgets(buf, 256, fp) == NULL)
					break;

				sscanf(buf, "%d %d %d %d\n", &inu, &a, &b, &c);
				AddTri(a, b, c);

				if ((i%200) == 0 && progress_callback != NULL)
				{
					if (progress_callback(49 + i * 50 / num_faces))
					{
						fclose(fp);
						return false;	// user cancelled
					}
				}
			}
		}
	}
	fclose(fp);
	ComputeExtents();
	return true;
}