static void test_clip_line() { GeoClip clip(GeoBounds(make_geo_point(2, 5), make_geo_point(6, 1))); /* no clipping */ test_clip_line(clip, make_geo_point(2, 5), make_geo_point(6, 1), make_geo_point(2, 5), make_geo_point(6, 1)); /* clipping at east border */ test_clip_line(clip, make_geo_point(2, 4), make_geo_point(7, 4), make_geo_point(2, 4), make_geo_point(6, 4)); /* clipping east & west */ test_clip_line(clip, make_geo_point(1, 4), make_geo_point(7, 4), make_geo_point(2, 4), make_geo_point(6, 4)); /* clipping north */ test_clip_line(clip, make_geo_point(3, 7), make_geo_point(3, 2), make_geo_point(3, 5), make_geo_point(3, 2)); /* clipping north & south */ test_clip_line(clip, make_geo_point(3, 7), make_geo_point(3, -1000), make_geo_point(3, 5), make_geo_point(3, 1)); /* clipping southwest */ test_clip_line(clip, make_geo_point(5, 2), make_geo_point(7, 0), make_geo_point(5, 2), make_geo_point(6, 1)); /* clipping northwest & southeast */ test_clip_line(clip, make_geo_point(0, 9), make_geo_point(9, -3), make_geo_point(3, 5), make_geo_point(6, 1)); }
GeoBounds FlatProjection::Unproject(const FlatBoundingBox &bb) const { assert(IsValid()); return GeoBounds(Unproject(bb.GetTopLeft()), Unproject(bb.GetBottomRight())); }
static inline constexpr GeoBounds ImportRect(const rectObj r) { return GeoBounds(GeoPoint(Angle::Degrees(fixed(r.minx)), Angle::Degrees(fixed(r.maxy))), GeoPoint(Angle::Degrees(fixed(r.maxx)), Angle::Degrees(fixed(r.miny)))); }
GeoBounds TaskProjection::unproject(const FlatBoundingBox& bb) const { assert(initialised); return GeoBounds (unproject(FlatGeoPoint(bb.bb_ll.Longitude, bb.bb_ur.Latitude)), unproject(FlatGeoPoint(bb.bb_ur.Longitude, bb.bb_ll.Latitude))); }
GeoBounds GeoQuadrilateral::GetBounds() const { const auto longitude = std::minmax({top_left.longitude, top_right.longitude, bottom_left.longitude, bottom_right.longitude}); const auto latitude = std::minmax({top_left.latitude, top_right.latitude, bottom_left.latitude, bottom_right.latitude}); return GeoBounds(GeoPoint(longitude.first, latitude.second), GeoPoint(longitude.second, latitude.first)); }
GeoBounds FlatProjection::Unproject(const FlatBoundingBox &bb) const { assert(IsValid()); return GeoBounds(Unproject(FlatGeoPoint(bb.GetLowerLeft().longitude, bb.GetUpperRight().latitude)), Unproject(FlatGeoPoint(bb.GetUpperRight().longitude, bb.GetLowerLeft().latitude))); }
GeoBounds ToGeoBounds(unsigned width, unsigned height) const { const Angle lon_min(Angle::Degrees(x_origin)); const Angle lon_max(Angle::Degrees(x_origin + width * x_scale)); const Angle lat_min(Angle::Degrees(y_origin)); const Angle lat_max(Angle::Degrees(y_origin + height * y_scale)); return GeoBounds(GeoPoint(std::min(lon_min, lon_max), std::max(lat_min, lat_max)), GeoPoint(std::max(lon_min, lon_max), std::min(lat_min, lat_max))); }
GeoBounds SearchPointVector::CalculateGeoBounds() const { if (empty()) return GeoBounds(GeoPoint(Angle::zero(), Angle::zero())); GeoBounds bb((*this)[0].get_location()); for (const_iterator v = begin(); v != end(); ++v) bb.extend(v->get_location()); return bb; }
void GeoBounds::Extend(const GeoPoint pt) { if (!pt.IsValid()) return; if (IsValid()) { longitude.Extend(pt.longitude); latitude.Extend(pt.latitude); } else { *this = GeoBounds(pt); } }
static GeoBounds MakeGeoBounds(int west, int north, int east, int south) { return GeoBounds(GeoPoint(Angle::Degrees(west), Angle::Degrees(north)), GeoPoint(Angle::Degrees(east), Angle::Degrees(south))); }
static void test_clip_polygon() { GeoClip clip(GeoBounds(make_geo_point(2, 5), make_geo_point(6, 1))); /* invalid polygon */ const GeoPoint src1[2]; test_clip_polygon(clip, src1, 0, NULL, 0); test_clip_polygon(clip, src1, 1, NULL, 0); test_clip_polygon(clip, src1, 2, NULL, 0); /* no clipping */ const GeoPoint src2[3] = { make_geo_point(3, 4), make_geo_point(5, 4), make_geo_point(3, 2), }; test_clip_polygon(clip, src2, 3, src2, 3); /* one vertex clipped */ const GeoPoint src3[3] = { make_geo_point(3, 4), make_geo_point(9, 4), make_geo_point(3, 2), }; const GeoPoint result3[4] = { make_geo_point(3, 4), make_geo_point(6, 4), make_geo_point(6, 3), make_geo_point(3, 2), }; test_clip_polygon(clip, src3, 3, result3, 4); /* two vertices clipped */ const GeoPoint src4[3] = { make_geo_point(1, 4), make_geo_point(9, 4), make_geo_point(3, 2), }; const GeoPoint result4[5] = { make_geo_point(2, 3), make_geo_point(2, 4), make_geo_point(6, 4), make_geo_point(6, 3), make_geo_point(3, 2), }; test_clip_polygon(clip, src4, 3, result4, 5); /* clipping a secant */ const GeoPoint src5[3] = { make_geo_point(1, 2), make_geo_point(3, 2), make_geo_point(3, 0), }; const GeoPoint result5[4] = { make_geo_point(2, 1), make_geo_point(2, 2), make_geo_point(3, 2), make_geo_point(3, 1), }; test_clip_polygon(clip, src5, 3, result5, 4); /* all four vertices clipped */ const GeoPoint src6[4] = { make_geo_point(1, 3), make_geo_point(4, 6), make_geo_point(7, 3), make_geo_point(4, 0), }; const GeoPoint result6[8] = { make_geo_point(2, 4), make_geo_point(3, 5), make_geo_point(5, 5), make_geo_point(6, 4), make_geo_point(6, 2), make_geo_point(5, 1), make_geo_point(3, 1), make_geo_point(2, 2), }; test_clip_polygon(clip, src6, 4, result6, 8); /* rectangle full clip */ const GeoPoint src7[4] = { make_geo_point(-10, -10), make_geo_point(-10, 10), make_geo_point(10, 10), make_geo_point(10, -10), }; const GeoPoint result7[4] = { make_geo_point(2, 1), make_geo_point(2, 5), make_geo_point(6, 5), make_geo_point(6, 1), }; test_clip_polygon(clip, src7, 4, result7, 4); /* triangle full clip */ const GeoPoint src8[3] = { make_geo_point(-10, 50), make_geo_point(50, 5), make_geo_point(-5, -50), }; test_clip_polygon(clip, src8, 3, result7, 4); }
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 = GeoBounds(GeoPoint(Angle::Degrees(fixed(shape.bounds.minx)), Angle::Degrees(fixed(shape.bounds.maxy))), GeoPoint(Angle::Degrees(fixed(shape.bounds.maxx)), Angle::Degrees(fixed(shape.bounds.miny)))); #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); }