예제 #1
0
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();
}
예제 #2
0
파일: Topology.cpp 프로젝트: Mazuk/LK8000
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;
        }
    }
예제 #3
0
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;
    }
  }
}