예제 #1
0
파일: XShape.cpp 프로젝트: Plantain/XCSoar
XShape::XShape(shapefileObj *shpfile, int i, int label_field)
  :label(NULL)
{
  msInitShape(&shape);
  msSHPReadShape(shpfile->hSHP, i, &shape);

#ifdef RADIANS
  for (int tt = 0; tt < shape.numlines; ++tt) {
    for (int jj = 0; jj < shape.line[tt].numpoints; ++jj) {
      shape.line[tt].point[jj].x *= DEG_TO_RAD;
      shape.line[tt].point[jj].y *= DEG_TO_RAD;
    }
  }
#endif

  if (label_field >= 0) {
    const char *src = msDBFReadStringAttribute(shpfile->hDBF, i, label_field);
    label = import_label(src);
  }
}
예제 #2
0
XShape::XShape(shapefileObj *shpfile, int i, int label_field)
  :label(NULL)
{
#ifdef ENABLE_OPENGL
  for (unsigned l=0; l < THINNING_LEVELS; l++)
    index_count[l] = indices[l] = NULL;
#endif

  shapeObj shape;
  msInitShape(&shape);
  msSHPReadShape(shpfile->hSHP, i, &shape);

  bounds.west = Angle::Degrees(fixed(shape.bounds.minx));
  bounds.south = Angle::Degrees(fixed(shape.bounds.miny));
  bounds.east = Angle::Degrees(fixed(shape.bounds.maxx));
  bounds.north = Angle::Degrees(fixed(shape.bounds.maxy));
#ifdef ENABLE_OPENGL
  center = bounds.GetCenter();
#endif

  type = shape.type;

  num_lines = 0;

  const int min_points = min_points_for_type(shape.type);
  if (min_points < 0) {
    /* not supported, leave an empty XShape object */
    points = NULL;
    msFreeShape(&shape);
    return;
  }

  const unsigned input_lines = std::min((unsigned)shape.numlines,
                                        (unsigned)MAX_LINES);
  unsigned num_points = 0;
  for (unsigned l = 0; l < input_lines; ++l) {
    if (shape.line[l].numpoints < min_points)
      /* malformed shape */
      continue;

    lines[num_lines] = std::min(shape.line[l].numpoints, 16384);
    num_points += lines[num_lines];
    ++num_lines;
  }

#ifdef ENABLE_OPENGL
  /* OpenGL:
   * Convert all points of all lines to ShapePoints, using a projection
   * that assumes the center of the screen is also the center of the shape.
   * Resolution is set to 1m per pixel. This enables us to use a simple matrix
   * multiplication to draw the shape.
   * This approximation should work well with shapes of limited size
   * (<< 400km). Perceivable distortion will only happen, when the latitude of
   * the actual center of the screen is far away from the latitude of the
   * center of the shape and the shape has a big vertical size.
   */

  points = new ShapePoint[num_points];
  ShapePoint *p = points;
#else // !ENABLE_OPENGL
  /* convert all points of all lines to GeoPoints */

  points = new GeoPoint[num_points];
  GeoPoint *p = points;
#endif
  for (unsigned l = 0; l < num_lines; ++l) {
    const pointObj *src = shape.line[l].point;
    num_points = lines[l];
    for (unsigned j = 0; j < num_points; ++j, ++src)
#ifdef ENABLE_OPENGL
      *p++ = geo_to_shape(GeoPoint(Angle::Degrees(fixed(src->x)),
                                   Angle::Degrees(fixed(src->y))));
#else
      *p++ = GeoPoint(Angle::Degrees(fixed(src->x)),
                      Angle::Degrees(fixed(src->y)));
#endif
  }

  if (label_field >= 0) {
    const char *src = msDBFReadStringAttribute(shpfile->hDBF, i, label_field);
    label = import_label(src);
  }

  msFreeShape(&shape);
}
예제 #3
0
파일: XShape.cpp 프로젝트: Adrien81/XCSoar
XShape::XShape(shapefileObj *shpfile, const GeoPoint &file_center, int i,
               int label_field)
  :label(nullptr)
{
#ifdef ENABLE_OPENGL
  std::fill_n(index_count, THINNING_LEVELS, nullptr);
  std::fill_n(indices, THINNING_LEVELS, nullptr);
#endif

  shapeObj shape;
  msInitShape(&shape);
  msSHPReadShape(shpfile->hSHP, i, &shape);

  bounds = ImportRect(shape.bounds);

  type = shape.type;

  num_lines = 0;

  const int min_points = min_points_for_type(shape.type);
  if (min_points < 0) {
    /* not supported, leave an empty XShape object */
    points = nullptr;
    msFreeShape(&shape);
    return;
  }

  const unsigned input_lines = std::min((unsigned)shape.numlines,
                                        (unsigned)MAX_LINES);
  unsigned num_points = 0;
  for (unsigned l = 0; l < input_lines; ++l) {
    if (shape.line[l].numpoints < min_points)
      /* malformed shape */
      continue;

    lines[num_lines] = std::min(shape.line[l].numpoints, 16384);
    num_points += lines[num_lines];
    ++num_lines;
  }

#ifdef ENABLE_OPENGL
  /* OpenGL: convert GeoPoints to ShapePoints, make them relative to
     the map's boundary center */

  points = new ShapePoint[num_points];
  ShapePoint *p = points;
#else // !ENABLE_OPENGL
  /* convert all points of all lines to GeoPoints */

  points = new GeoPoint[num_points];
  GeoPoint *p = points;
#endif
  for (unsigned l = 0; l < num_lines; ++l) {
    const pointObj *src = shape.line[l].point;
    num_points = lines[l];
    for (unsigned j = 0; j < num_points; ++j, ++src) {
#ifdef ENABLE_OPENGL
      const GeoPoint vertex(Angle::Degrees(src->x), Angle::Degrees(src->y));
      const GeoPoint relative = vertex - file_center;

      *p++ = ShapePoint(ShapeScalar(relative.longitude.Native()),
                        ShapeScalar(relative.latitude.Native()));
#else
      *p++ = GeoPoint(Angle::Degrees(fixed(src->x)),
                      Angle::Degrees(fixed(src->y)));
#endif
    }
  }

  if (label_field >= 0) {
    const char *src = msDBFReadStringAttribute(shpfile->hDBF, i, label_field);
    label = import_label(src);
  }

  msFreeShape(&shape);
}