void GLShapeRenderer::renderPolygon(LKSurface& Surface, const XShape& shape, Brush& brush, const ScreenProjection& _Proj) { /* OpenGL cannot draw complex polygons so we need to use a Tessallator to draw the polygon using a GL_TRIANGLE_FAN */ #ifdef USE_GLSL OpenGL::solid_shader->Use(); #endif brush.Bind(); std::unique_ptr<const GLBlend> blend; if(!brush.IsOpaque()) { blend = std::make_unique<const GLBlend>(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } curr_LabelPos = clipRect.GetBottomRight(); const shapeObj& shp = shape.shape; gluTessBeginPolygon(tess, this ); for (int j = 0; j < shp.numlines; j++) { gluTessBeginContour(tess); for (int i = 0; i < shp.line[j].numpoints; i++) { const RasterPoint pt = _Proj.LonLat2Screen(shp.line[j].point[i]); if (!noLabel && (pt.x<=curr_LabelPos.x)) { curr_LabelPos = pt; } vertex_t& vertex = *(pointers.insert(pointers.end(), vertex_t({{(GLdouble)pt.x, (GLdouble)pt.y, 0.}}))); gluTessVertex(tess, vertex.data(), vertex.data()); } gluTessEndContour(tess); } gluTessEndPolygon(tess); if(shape.HasLabel() && clipRect.IsInside(curr_LabelPos)) { shape.renderSpecial(Surface, curr_LabelPos.x, curr_LabelPos.y, clipRect); } pointers.clear(); }
void TopographyFileRenderer::PaintPoint(Canvas &canvas, const WindowProjection &projection, const XShape &shape, float *opengl_matrix) const { if (!icon.IsDefined()) return; // TODO: for now i assume there is only one point for point-XShapes RasterPoint sc; if (!projection.GeoToScreenIfVisible(shape.get_center(), sc)) return; #ifndef HAVE_GLES glPushMatrix(); glLoadMatrixf(opengl_matrix); #endif icon.Draw(canvas, sc.x, sc.y); #ifndef HAVE_GLES glPopMatrix(); #endif }
void Topology::Paint(HDC hdc, RECT rc) { if (!shapefileopen) return; bool nolabels=false; if (scaleCategory==10) { // for water areas, use scaleDefault if ( MapWindow::zoom.RealScale()>scaleDefaultThreshold) { return; } // since we just checked category 10, if we are over scale we set nolabels if ( MapWindow::zoom.RealScale()>scaleThreshold) nolabels=true; } else if (MapWindow::zoom.RealScale() > scaleThreshold) return; // TODO code: only draw inside screen! // this will save time with rendering pixmaps especially // checkVisible does only check lat lon , not screen pixels.. // We need to check also screen. HPEN hpOld; HBRUSH hbOld; HFONT hfOld; if (hPen) { hpOld = (HPEN)SelectObject(hdc, hPen); hbOld = (HBRUSH)SelectObject(hdc, hbBrush); } else { hpOld = NULL; hbOld = NULL; } hfOld = (HFONT)SelectObject(hdc, MapLabelFont); // get drawing info int iskip = 1; // attempt to bugfix 100615 polyline glitch with zoom over 33Km // do not skip points, if drawing coast lines which have a scaleThreshold of 100km! // != 5 and != 10 if (scaleCategory>10) { if (MapWindow::zoom.RealScale()>0.25*scaleThreshold) { iskip = 2; } if (MapWindow::zoom.RealScale()>0.5*scaleThreshold) { iskip = 3; } if (MapWindow::zoom.RealScale()>0.75*scaleThreshold) { iskip = 4; } } #if TOPOFASTLABEL // use the already existing screenbounds_latlon, calculated by CalculateScreenPositions in MapWindow2 rectObj screenRect = MapWindow::screenbounds_latlon; #else rectObj screenRect = MapWindow::CalculateScreenBounds(0.0); #endif static POINT pt[MAXCLIPPOLYGON]; bool labelprinted=false; for (int ixshp = 0; ixshp < shpfile.numshapes; ixshp++) { XShape *cshape = shpCache[ixshp]; if (!cshape || cshape->hide) continue; shapeObj *shape = &(cshape->shape); switch(shape->type) { case(MS_SHAPE_POINT): { #if 101016 // -------------------------- NOT PRINTING ICONS --------------------------------------------- bool dobitmap=false; if (scaleCategory<90 || (MapWindow::zoom.RealScale()<2)) dobitmap=true; // first a latlon overlap check, only approximated because of fastcosine in latlon2screen if (checkVisible(*shape, screenRect)) for (int tt = 0; tt < shape->numlines; tt++) { for (int jj=0; jj< shape->line[tt].numpoints; jj++) { POINT sc; MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc); if (dobitmap) { // bugfix 101212 missing case for scaleCategory 0 (markers) if (scaleCategory==0||cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted)) MapWindow::DrawBitmapIn(hdc, sc, hBitmap,true); } else { cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted); } } } } #else // -------------------------- PRINTING ICONS --------------------------------------------- #if (TOPOFAST) // no bitmaps for small town over a certain zoom level and no bitmap if no label at all levels bool nobitmap=false, noiconwithnolabel=false; if (scaleCategory==90 || scaleCategory==100) { noiconwithnolabel=true; if (MapWindow::MapScale>4) nobitmap=true; } #endif //#if TOPOFASTLABEL if (checkVisible(*shape, screenRect)) for (int tt = 0; tt < shape->numlines; tt++) { for (int jj=0; jj< shape->line[tt].numpoints; jj++) { POINT sc; MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc); #if (TOPOFAST) if (!nobitmap) #endif #if 101016 // only paint icon if label is printed too if (noiconwithnolabel) { if (cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted)) MapWindow::DrawBitmapIn(hdc, sc, hBitmap,true); } else { MapWindow::DrawBitmapIn(hdc, sc, hBitmap,true); cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted); } #else MapWindow::DrawBitmapIn(hdc, sc, hBitmap,true); cshape->renderSpecial(hdc, sc.x, sc.y); #endif } } } #endif // Use optimized point icons 1.23e break; case(MS_SHAPE_LINE): if (checkVisible(*shape, screenRect)) for (int tt = 0; tt < shape->numlines; tt ++) { int minx = rc.right; int miny = rc.bottom; int msize = min(shape->line[tt].numpoints, MAXCLIPPOLYGON); MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize, 1); for (int jj=0; jj< msize; jj++) { if (pt[jj].x<=minx) { minx = pt[jj].x; miny = pt[jj].y; } } ClipPolygon(hdc, pt, msize, rc, false); cshape->renderSpecial(hdc,minx,miny,labelprinted); } break; case(MS_SHAPE_POLYGON): // if it's a water area (nolabels), print shape up to defaultShape, but print // labels only up to custom label levels if ( nolabels ) { if (checkVisible(*shape, screenRect)) { for (int tt = 0; tt < shape->numlines; tt ++) { int minx = rc.right; int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON); MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip); for (int jj=0; jj< msize; jj++) { if (pt[jj].x<=minx) { minx = pt[jj].x; } } ClipPolygon(hdc,pt, msize, rc, true); } } } else if (checkVisible(*shape, screenRect)) { for (int tt = 0; tt < shape->numlines; tt ++) { int minx = rc.right; int miny = rc.bottom; int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON); MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip); for (int jj=0; jj< msize; jj++) { if (pt[jj].x<=minx) { minx = pt[jj].x; miny = pt[jj].y; } } ClipPolygon(hdc,pt, msize, rc, true); cshape->renderSpecial(hdc,minx,miny,labelprinted); } } break; default: break; } }
XShape* Topology::addShape(const int i) { XShape* theshape = new XShape(); LKASSERT(theshape); theshape->load(&shpfile,i); return theshape; }
void Topology::Paint(Canvas &canvas, MapWindow &m_window, const RECT rc) { if (!shapefileopen) return; MapWindowProjection &map_projection = m_window; LabelBlock *label_block = m_window.getLabelBlock(); double map_scale = map_projection.GetMapScaleUser(); if (map_scale > scaleThreshold) return; // TODO code: only draw inside screen! // this will save time with rendering pixmaps especially // we already do an outer visibility test, but may need a test // in screen coords canvas.select(hPen); canvas.select(hbBrush); canvas.select(MapLabelFont); // get drawing info int iskip = 1; if (map_scale>0.25*scaleThreshold) { iskip = 2; } if (map_scale>0.5*scaleThreshold) { iskip = 3; } if (map_scale>0.75*scaleThreshold) { iskip = 4; } rectObj screenRect = map_projection.CalculateScreenBounds(0.0); static POINT pt[MAXCLIPPOLYGON]; const bool render_labels = (m_window.SettingsMap().DeclutterLabels<2); for (int ixshp = 0; ixshp < shpfile.numshapes; ixshp++) { XShape *cshape = shpCache[ixshp]; if (!cshape || cshape->hide) continue; shapeObj *shape = &(cshape->shape); switch(shape->type) { case(MS_SHAPE_POINT):{ if (checkVisible(*shape, screenRect)) { for (int tt = 0; tt < shape->numlines; tt++) { for (int jj=0; jj< shape->line[tt].numpoints; jj++) { POINT sc; GEOPOINT l; l.Longitude = shape->line[tt].point[jj].x; l.Latitude = shape->line[tt].point[jj].y; if (m_window.draw_masked_bitmap_if_visible(canvas, hBitmap, l, 10, 10, &sc)) { if (render_labels) cshape->renderSpecial(canvas, *label_block, sc.x, sc.y); } } } } }; break; case(MS_SHAPE_LINE): if (checkVisible(*shape, screenRect)) for (int tt = 0; tt < shape->numlines; tt ++) { int minx = rc.right; int miny = rc.bottom; int msize = min(shape->line[tt].numpoints, MAXCLIPPOLYGON); map_projection.LonLat2Screen(shape->line[tt].point, pt, msize, 1); for (int jj=0; jj< msize; jj++) { if (pt[jj].x<=minx) { minx = pt[jj].x; miny = pt[jj].y; } } canvas.polyline(pt, msize); if (render_labels) cshape->renderSpecial(canvas, *label_block, minx, miny); } break; case(MS_SHAPE_POLYGON): if (checkVisible(*shape, screenRect)) for (int tt = 0; tt < shape->numlines; tt ++) { int minx = rc.right; int miny = rc.bottom; int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON); map_projection.LonLat2Screen(shape->line[tt].point, pt, msize*iskip, iskip); for (int jj=0; jj< msize; jj++) { if (pt[jj].x<=minx) { minx = pt[jj].x; miny = pt[jj].y; } } canvas.polygon(pt, msize); if (render_labels) cshape->renderSpecial(canvas, *label_block, minx, miny); } break; default: break; } } }