void TopographyStore::Load(OperationEnvironment &operation, NLineReader &reader, const TCHAR *directory, struct zzip_dir *zdir) { Reset(); // Create buffer for the shape filenames // (shape_filename will be modified with the shape_filename_end pointer) char shape_filename[MAX_PATH]; if (directory != nullptr) { const WideToACPConverter narrow_directory(directory); strcpy(shape_filename, narrow_directory); strcat(shape_filename, DIR_SEPARATOR_S); } else shape_filename[0] = 0; char *shape_filename_end = shape_filename + strlen(shape_filename); // Read file size to have a rough progress estimate for the progress bar const long filesize = std::max(reader.GetSize(), 1l); // Set progress bar to 100 steps operation.SetProgressRange(100); // Iterate through shape files in the "topology.tpl" file until // end or max. file number reached char *line; while (!files.full() && (line = reader.ReadLine()) != nullptr) { // .tpl Line format: filename,range,icon,field,r,g,b,pen_width,label_range,important_range,alpha // Ignore comments (lines starting with *) and empty lines if (StringIsEmpty(line) || line[0] == '*') continue; // Find first comma to extract shape filename char *p = strchr(line, ','); if (p == nullptr || p == line) // If no comma was found -> ignore this line/shapefile continue; if (HasLittleMemory()) { /* hard-coded blacklist for huge files on PPC2000; those devices usually have very little memory */ // Null-terminate the line string after the first comma // for strcmp() calls in IsHugeTopographyFile() function *p = 0; // Skip large topography files if (IsHugeTopographyFile(line)) continue; } // Extract filename and append it to the shape_filename buffer memcpy(shape_filename_end, line, p - line); // Append ".shp" file extension to the shape_filename buffer strcpy(shape_filename_end + (p - line), ".shp"); // Parse shape range fixed shape_range = fixed(strtod(p + 1, &p)) * 1000; if (*p != _T(',')) continue; // Extract shape icon name char icon_name[23]; char *start = p + 1; p = strchr(start, ','); // Null-terminate the line string at the next comma for strncpy() call *p = 0; strncpy(icon_name, start, 22); ResourceId icon = ResourceId::Null(), big_icon = ResourceId::Null(); if (strlen(icon_name) > 0) { const LOOKUP_ICON *ip = icon_list; while (ip->name != nullptr) { if (StringIsEqual(ip->name, icon_name)) { icon = ip->resource_id; big_icon = ip->big_resource_id; break; } ip++; } } // Parse shape field for text display long shape_field = strtol(p + 1, &p, 10) - 1; if (*p != _T(',')) continue; // Parse red component of line / shading colour uint8_t red = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse green component of line / shading colour uint8_t green = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse blue component of line / shading colour uint8_t blue = (uint8_t)strtol(p + 1, &p, 10); // Parse pen width of lines unsigned pen_width = 1; if (*p == _T(',')) { pen_width = strtoul(p + 1, &p, 10); if (pen_width < 1) pen_width = 1; else if (pen_width>31) pen_width=31; } // Parse range for displaying labels fixed label_range = shape_range; if (*p == _T(',')) label_range = fixed(strtod(p + 1, &p)) * 1000; // Parse range for displaying labels with "important" rendering style fixed labelImportantRange = fixed(0); if (*p == _T(',')) labelImportantRange = fixed(strtod(p + 1, &p)) * 1000; // Handle alpha component // If not present at all (i.e. v6.6 or earlier file), default to 100% opaque uint8_t alpha = 255; if (*p == _T(',')) { // An alpha component of shading colour is present (v6.7 or later file). alpha = (uint8_t)strtol(p + 1, &p, 10); // Ignore a totally transparent file! if (alpha == 0) continue; #ifndef ENABLE_OPENGL // Without OpenGL ignore anything but 100% opaque if (alpha != 255) continue; #endif } // Create TopographyFile instance from parsed line TopographyFile *file = new TopographyFile(zdir, shape_filename, shape_range, label_range, labelImportantRange, #ifdef ENABLE_OPENGL Color(red, green, blue, alpha), #else Color(red, green, blue), #endif shape_field, icon, big_icon, pen_width); if (file->IsEmpty()) // If the shape file could not be read -> skip this line/file delete file; else // .. otherwise append it to our list of shape files files.append(file); // Update progress bar operation.SetProgressPosition((reader.Tell() * 100) / filesize); } }
void TopographyStore::Load(OperationEnvironment &operation, NLineReader &reader, const TCHAR *directory, struct zzip_dir *zdir) { Reset(); // Create buffer for the shape filenames // (shape_filename will be modified with the shape_filename_end pointer) char shape_filename[MAX_PATH]; if (directory != NULL) { const WideToACPConverter narrow_directory(directory); strcpy(shape_filename, narrow_directory); strcat(shape_filename, DIR_SEPARATOR_S); } else shape_filename[0] = 0; char *shape_filename_end = shape_filename + strlen(shape_filename); // Read file size to have a rough progress estimate for the progress bar long filesize = std::max(reader.size(), 1l); // Set progress bar to 100 steps operation.SetProgressRange(100); // Iterate through shape files in the "topology.tpl" file until // end or max. file number reached char *line; while (!files.full() && (line = reader.read()) != NULL) { // Line format: filename,range,icon,field,r,g,b,pen_width,label_range,important_range // Ignore comments (lines starting with *) and empty lines if (StringIsEmpty(line) || line[0] == '*') continue; // Find first comma to extract shape filename char *p = strchr(line, ','); if (p == NULL || p == line) // If no comma was found -> ignore this line/shapefile continue; if (HasLittleMemory()) { /* hard-coded blacklist for huge files on PPC2000; those devices usually have very little memory */ // Null-terminate the line string after the first comma // for strcmp() calls in IsHugeTopographyFile() function *p = 0; // Skip large topography files if (IsHugeTopographyFile(line)) continue; } // Extract filename and append it to the shape_filename buffer memcpy(shape_filename_end, line, p - line); // Append ".shp" file extension to the shape_filename buffer strcpy(shape_filename_end + (p - line), ".shp"); // Parse shape range fixed shape_range = fixed(strtod(p + 1, &p)) * 1000; if (*p != _T(',')) continue; // Parse shape icon id long shape_icon = strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse shape field for text display long shape_field = strtol(p + 1, &p, 10) - 1; if (*p != _T(',')) continue; // Parse red component of line / shading colour uint8_t red = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse green component of line / shading colour uint8_t green = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse blue component of line / shading colour uint8_t blue = (uint8_t)strtol(p + 1, &p, 10); // Parse pen width of lines int pen_width=1; if (*p == _T(',')) { pen_width = strtol(p + 1, &p, 10); if (pen_width<0) pen_width=1; else if (pen_width>31) pen_width=31; } // Parse range for displaying labels fixed label_range = shape_range; if (*p == _T(',')) label_range = fixed(strtod(p + 1, &p)) * 1000; // Parse range for displaying labels with "important" rendering style fixed labelImportantRange = fixed_zero; if (*p == _T(',')) labelImportantRange = fixed(strtod(p + 1, &p)) * 1000; // Create TopographyFile instance from parsed line TopographyFile *file = new TopographyFile(zdir, shape_filename, shape_range, label_range, labelImportantRange, Color(red, green, blue), shape_field, shape_icon, pen_width); if (file->IsEmpty()) // If the shape file could not be read -> skip this line/file delete file; else // .. otherwise append it to our list of shape files files.append(file); // Update progress bar operation.SetProgressPosition((reader.tell() * 100) / filesize); } }