示例#1
0
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);
  }
}
示例#2
0
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);
  }
}