void NativeFileImport::import(bool load_symbols_only)
{
    addWarning(Importer::tr("This file uses an obsolete format. "
                            "Support for this format is to be removed from this program soon. "
                            "To be able to open the file in the future, save it again."));

    MapCoord::boundsOffset().reset(true);

    char buffer[4];
    stream->read(buffer, 4); // read the magic

    int version;
    stream->read((char*)&version, sizeof(int));
    if (version < 0)
    {
        addWarning(Importer::tr("Invalid file format version."));
    }
    else if (version < NativeFileFormat::least_supported_file_format_version)
    {
        throw FileFormatException(Importer::tr("Unsupported old file format version. Please use an older program version to load and update the file."));
    }
    else if (version > NativeFileFormat::current_file_format_version)
    {
        throw FileFormatException(Importer::tr("Unsupported new file format version. Some map features will not be loaded or saved by this version of the program. Consider updating."));
    }

    if (version <= 16)
	{
		Georeferencing georef;
		stream->read((char*)&georef.scale_denominator, sizeof(int));
		
		if (version >= 15)
			loadString(stream, map->map_notes);
		
		bool gps_projection_params_set; // obsolete
		stream->read((char*)&gps_projection_params_set, sizeof(bool));
		GPSProjectionParameters gps_projection_parameters; // obsolete
		stream->read((char*)&gps_projection_parameters, sizeof(GPSProjectionParameters));
		if (gps_projection_params_set)
		{
			LatLon ref_point = LatLon::fromRadiant(gps_projection_parameters.center_latitude, gps_projection_parameters.center_longitude);
			georef.setGeographicRefPoint(ref_point);
		}
		*map->georeferencing = georef;
	}
	else if (version >= 17)
	{
		loadString(stream, map->map_notes);
		
		Georeferencing georef;
		stream->read((char*)&georef.scale_denominator, sizeof(int));
		double value;
		if (version >= 18)
		{
			stream->read((char*)&value, sizeof(double));
			georef.declination = Georeferencing::roundDeclination(value);
		}
		stream->read((char*)&value, sizeof(double));
		georef.grivation = Georeferencing::roundDeclination(value);
		georef.grivation_error = value - georef.grivation;
		
		double x,y;
		stream->read((char*)&x, sizeof(double));
		stream->read((char*)&y, sizeof(double));
		georef.map_ref_point = MapCoord(x,y);
		stream->read((char*)&x, sizeof(double));
		stream->read((char*)&y, sizeof(double));
		georef.projected_ref_point = QPointF(x,y);
		loadString(stream, georef.projected_crs_id);
		loadString(stream, georef.projected_crs_spec);
		stream->read((char*)&y, sizeof(double));
		stream->read((char*)&x, sizeof(double));
		georef.geographic_ref_point = LatLon::fromRadiant(y, x); 
		QString geographic_crs_id, geographic_crs_spec;
		loadString(stream, geographic_crs_id);   // reserved for geographic crs id
		loadString(stream, geographic_crs_spec); // reserved for full geographic crs specification
		if (geographic_crs_spec != Georeferencing::geographic_crs_spec)
		{
			addWarning(
			  Importer::tr("The geographic coordinate reference system of the map was \"%1\". This CRS is not supported. Using \"%2\".").
			  arg(geographic_crs_spec).
			  arg(Georeferencing::geographic_crs_spec)
			);
		}
		if (version <= 17)
			georef.initDeclination();
		// Correctly set georeferencing state
		georef.setProjectedCRS(georef.projected_crs_id, georef.projected_crs_spec);
		*map->georeferencing = georef;
	}
	
	if (version >= 24)
		map->setGrid(MapGrid().load(stream, version));
	
	map->renderable_options = Symbol::RenderNormal;
	if (version >= 25)
	{
		bool area_hatching_enabled, baseline_view_enabled;
		stream->read((char*)&area_hatching_enabled, sizeof(bool));
		stream->read((char*)&baseline_view_enabled, sizeof(bool));
		if (area_hatching_enabled)
			map->renderable_options |= Symbol::RenderAreasHatched;
		if (baseline_view_enabled)
			map->renderable_options |= Symbol::RenderBaselines;
	}
	
	if (version >= 6)
	{
		bool print_params_set;
		stream->read((char*)&print_params_set, sizeof(bool));
		if (print_params_set)
		{
			MapPrinterConfig printer_config(*map);
			stream->read((char*)&printer_config.page_format.orientation, sizeof(int));
			stream->read((char*)&printer_config.page_format.paper_size, sizeof(int));
			
			float resolution;
			stream->read((char*)&resolution, sizeof(float));
			printer_config.options.resolution = qRound(resolution);
			stream->read((char*)&printer_config.options.show_templates, sizeof(bool));
			if (version >= 24)
				stream->read((char*)&printer_config.options.show_grid, sizeof(bool));
			else
				printer_config.options.show_grid = false;
			
			stream->read((char*)&printer_config.center_print_area, sizeof(bool));
			
			float print_area_left, print_area_top, print_area_width, print_area_height;
			stream->read((char*)&print_area_left, sizeof(float));
			stream->read((char*)&print_area_top, sizeof(float));
			stream->read((char*)&print_area_width, sizeof(float));
			stream->read((char*)&print_area_height, sizeof(float));
			printer_config.print_area = QRectF(print_area_left, print_area_top, print_area_width, print_area_height);
			
			if (version >= 26)
			{
				bool print_different_scale_enabled;
				stream->read((char*)&print_different_scale_enabled, sizeof(bool));
				stream->read((char*)&printer_config.options.scale, sizeof(int));
				if (!print_different_scale_enabled)
					printer_config.options.scale = map->getScaleDenominator();
			}
			map->setPrinterConfig(printer_config);
		}
	}
	
    if (version >= 16)
	{
		stream->read((char*)&map->image_template_use_meters_per_pixel, sizeof(bool));
		stream->read((char*)&map->image_template_meters_per_pixel, sizeof(double));
		stream->read((char*)&map->image_template_dpi, sizeof(double));
		stream->read((char*)&map->image_template_scale, sizeof(double));
	}

    // Load colors
    int num_colors;
    stream->read((char*)&num_colors, sizeof(int));
    map->color_set->colors.resize(num_colors);

    for (int i = 0; i < num_colors; ++i)
    {
        int priority;
        stream->read((char*)&priority, sizeof(int));
        MapColor* color = new MapColor(priority);

        MapColorCmyk cmyk;
        stream->read((char*)&cmyk.c, sizeof(float));
        stream->read((char*)&cmyk.m, sizeof(float));
        stream->read((char*)&cmyk.y, sizeof(float));
        stream->read((char*)&cmyk.k, sizeof(float));
        color->setCmyk(cmyk);
        float opacity;
        stream->read((char*)&opacity, sizeof(float));
        color->setOpacity(opacity);

        QString name;
        loadString(stream, name);
        color->setName(name);

        map->color_set->colors[i] = color;
    }

    // Load symbols
    int num_symbols;
    stream->read((char*)&num_symbols, sizeof(int));
    map->symbols.resize(num_symbols);

    for (int i = 0; i < num_symbols; ++i)
    {
        QScopedValueRollback<MapCoord::BoundsOffset> offset { MapCoord::boundsOffset() };
        MapCoord::boundsOffset().reset(false);

        int symbol_type;
        stream->read((char*)&symbol_type, sizeof(int));

        Symbol* symbol = Symbol::getSymbolForType(static_cast<Symbol::Type>(symbol_type));
        if (!symbol)
        {
            throw FileFormatException(Importer::tr("Error while loading a symbol with type %2.").arg(symbol_type));
        }

        if (!symbol->load(stream, version, map))
        {
            throw FileFormatException(Importer::tr("Error while loading a symbol."));
        }
        map->symbols[i] = symbol;
    }

    if (!load_symbols_only)
	{
		// Load templates
		stream->read((char*)&map->first_front_template, sizeof(int));

		int num_templates;
		stream->read((char*)&num_templates, sizeof(int));
		map->templates.resize(num_templates);

		for (int i = 0; i < num_templates; ++i)
		{
			QString path;
			loadString(stream, path);
			auto temp = Template::templateForFile(path, map);
			if (!temp)
				temp.reset(new TemplateImage(path, map)); // fallback
			
			if (version >= 27)
			{
				loadString(stream, path);
				temp->setTemplateRelativePath(path);
			}
			
			temp->loadTemplateConfiguration(stream, version);

			map->templates[i] = temp.release();
		}
		
		if (version >= 28)
		{
			int num_closed_templates;
			stream->read((char*)&num_closed_templates, sizeof(int));
			map->closed_templates.resize(num_closed_templates);
			
			for (int i = 0; i < num_closed_templates; ++i)
			{
				QString path;
				loadString(stream, path);
				auto temp = Template::templateForFile(path, map);
				if (!temp)
					temp.reset(new TemplateImage(path, map)); // fallback
				
				loadString(stream, path);
				temp->setTemplateRelativePath(path);
				
				temp->loadTemplateConfiguration(stream, version);
				
				map->closed_templates[i] = temp.release();
			}
		}

		// Restore widgets and views
		if (view)
		{
			view->load(stream, version);
		}
		else
		{
			MapView tmp{ map };
			tmp.load(stream, version);
		}

		// Load undo steps
		if (version >= 7)
		{
			if (!map->undoManager().load(stream, version))
			{
				throw FileFormatException(Importer::tr("Error while loading undo steps."));
			}
		}

		// Load parts
		stream->read((char*)&map->current_part_index, sizeof(int));

		int num_parts;
		if (stream->read((char*)&num_parts, sizeof(int)) < (int)sizeof(int))
		{
			throw FileFormatException(Importer::tr("Error while reading map part count."));
		}
		delete map->parts[0];
		map->parts.resize(num_parts);

		for (int i = 0; i < num_parts; ++i)
		{
			MapPart* part = new MapPart({}, map);
			if (!part->load(stream, version, map))
			{
				throw FileFormatException(Importer::tr("Error while loading map part %2.").arg(i+1));
			}
			map->parts[i] = part;
		}
	}
	
	emit map->currentMapPartIndexChanged(map->current_part_index);
	emit map->currentMapPartChanged(map->getPart(map->current_part_index));
}
Exemple #2
0
static void ChangeDim( void )
{
	int x, y, x0, x1, y0, y1;
	coOrd p0;
	int size;
	bitmap_t tmpBm;
	BOOL_T selected;

	MapGrid( zero, mapD.size, 0.0, currPrintGrid.orig, currPrintGrid.angle, currPrintGrid.size.x, currPrintGrid.size.y,
		&x0, &x1, &y0, &y1 );
#ifdef LATER
	d0 = sqrt( mapD.size.x * mapD.size.x + mapD.size.y * mapD.size.y );

	Translate( &p1, currPrintGrid.orig, currPrintGrid.angle, d0 );
	p0 = currPrintGrid.orig;
	ClipLine( &p0, &p1, zero, 0.0, mapD.size );
	d1 = FindDistance( currPrintGrid.orig, p1 );
	y1 = (int)ceil(d1/currPrintGrid.size.y);

	Translate( &p1, currPrintGrid.orig, currPrintGrid.angle+180, d0 );
	p0 = currPrintGrid.orig;
	ClipLine( &p0, &p1, zero, 0.0, mapD.size );
	d1 = FindDistance( currPrintGrid.orig, p1 );
	y0 = -(int)floor(d1/currPrintGrid.size.y);

	Translate( &p1, currPrintGrid.orig, currPrintGrid.angle+90, d0 );
	p0 = currPrintGrid.orig;
	ClipLine( &p0, &p1, zero, 0.0, mapD.size );
	d1 = FindDistance( currPrintGrid.orig, p1 );
	x1 = (int)ceil(d1/currPrintGrid.size.x);

	Translate( &p1, currPrintGrid.orig, currPrintGrid.angle+270, d0 );
	p0 = currPrintGrid.orig;
	ClipLine( &p0, &p1, zero, 0.0, mapD.size );
	d1 = FindDistance( currPrintGrid.orig, p1 );
	x0 = -(int)floor(d1/currPrintGrid.size.x);
#endif

	if ( x0==bm.x0 && x1==bm.x1 && y0==bm.y0 && y1==bm.y1 )
		return;
	size = (x1-x0) * (y1-y0);
	if (size > bm0.memsize) {
		bm0.bm = MyRealloc( bm0.bm, size );
		bm0.memsize = size;
	}
	bm0.x0 = x0; bm0.x1 = x1; bm0.y0 = y0; bm0.y1 = y1;
	memset( bm0.bm, 0, bm0.memsize );
	pageCount = 0;
	if (bm.bm) {
		for ( x=bm.x0; x<bm.x1; x++ ) {
			for ( y=bm.y0; y<bm.y1; y++ ) {
				selected = BITMAP( bm, x, y );
				if (selected) {
					p0.x = bm.orig.x + x * bm.size.x + bm.size.x/2.0;
					p0.y = bm.orig.y + y * bm.size.y + bm.size.y/2.0;
					Rotate( &p0, bm.orig, bm.angle );
					p0.x -= currPrintGrid.orig.x;
					p0.y -= currPrintGrid.orig.y;
					Rotate( &p0, zero, -currPrintGrid.angle );
					x0 = (int)floor(p0.x/currPrintGrid.size.x);
					y0 = (int)floor(p0.y/currPrintGrid.size.y);
					if ( x0>=bm0.x0 && x0<bm0.x1 && y0>=bm0.y0 && y0<bm0.y1 ) {
						if ( BITMAP( bm0, x0, y0 ) == FALSE ) {
							pageCount++;
							BITMAP( bm0, x0, y0 ) = TRUE;
						}
					}
				}
			}
		}
	}
	tmpBm = bm0;
	bm0 = bm;
	bm = tmpBm;
	bm.orig = currPrintGrid.orig;
	bm.size = currPrintGrid.size;
	bm.angle = currPrintGrid.angle;
	sprintf( message, _("%d pages"), pageCount );
	ParamLoadMessage( &printPG, I_PAGECNT, message );
	ParamDialogOkActive( &printPG, pageCount!=0 );
}