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); } }
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); }
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); }