ui/src/main/java/ucar/nc2/ui/point/PointRenderer.java
public void draw(java.awt.Graphics2D g, java.awt.geom.AffineTransform normal2Device) {
    if ((project == null) || !posWasCalc) return;

    // use world coordinates for position, but draw in screen coordinates
    // so that the symbols stay the same size
    AffineTransform world2Device = g.getTransform();
    g.setTransform(normal2Device);        //  identity transform for screen coords

    // transform World to Normal coords:
    //    world2Normal = pixelAT-1 * world2Device
    // cache for pick closest
    AffineTransform world2Normal;
    try {
      world2Normal = normal2Device.createInverse();
      world2Normal.concatenate( world2Device);
    } catch ( java.awt.geom.NoninvertibleTransformException e) {
      System.out.println(
            " RendSurfObs: NoninvertibleTransformException on " +
            normal2Device);
      return;
    }

    // we want aliasing; but save previous state to restore at end
    Object saveHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
    //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    //    RenderingHints.VALUE_ANTIALIAS_ON);
    g.setStroke(new java.awt.BasicStroke(1.0f));

    /* set up the grid
    Rectangle2D bbox = (Rectangle2D) g.getClip(); // clipping area in normal coords
    // clear the grid = "no stations are drawn"
    stationGrid.clear();
    // set the grid size based on typical bounding box
    stationGrid.setGrid(bbox, typicalBB.getWidth(), typicalBB.getHeight());


    // always draw selected
    if (selected != null) {
      selected.calcPos( world2Normal);
      stationGrid.markIfClear( selected.getBB(), selected);
      selected.draw(g);
    } */

    g.setFont( textFont.getFont());
    g.setColor(color);

    int count = 0;
    int npts = obsUIlist.size();
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, npts);
    for (int i=0; i < npts; i++) {
      ObservationUI s = (ObservationUI) obsUIlist.get(i);
      s.calcPos(world2Normal);
      s.draw(g);

      if (Double.isNaN( s.screenPos.getX())) {
        System.out.println("screenPos="+s.screenPos+" world = "+s.worldPos);
        continue;
      }

      if (count == 0)
        path.moveTo( (float) s.screenPos.getX(), (float) s.screenPos.getY());
      else
        path.lineTo( (float) s.screenPos.getX(), (float) s.screenPos.getY());
      count++;
    }

    g.setColor(color);
    if (drawConnectingLine) 
      g.draw( path);

    // draw selected
    if (selected != null)
      selected.draw(g);

    // restore
    g.setTransform(world2Device);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, saveHint);
  }
public void draw(java.awt.Graphics2D g, java.awt.geom.AffineTransform normal2Device) {
    if ((project == null) || !posWasCalc) return;

    // use world coordinates for position, but draw in screen coordinates
    // so that the symbols stay the same size
    AffineTransform world2Device = g.getTransform();
    g.setTransform(normal2Device);        //  identity transform for screen coords

    // transform World to Normal coords:
    //    world2Normal = pixelAT-1 * world2Device
    // cache for pick closest
    AffineTransform world2Normal;
    try {
      world2Normal = normal2Device.createInverse();
      world2Normal.concatenate( world2Device);
    } catch ( java.awt.geom.NoninvertibleTransformException e) {
      System.out.println(
            " RendSurfObs: NoninvertibleTransformException on " +
            normal2Device);
      return;
    }

    // we want aliasing; but save previous state to restore at end
    Object saveHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
    //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    //    RenderingHints.VALUE_ANTIALIAS_ON);
    g.setStroke(new java.awt.BasicStroke(1.0f));

    /* set up the grid
    Rectangle2D bbox = (Rectangle2D) g.getClip(); // clipping area in normal coords
    // clear the grid = "no stations are drawn"
    stationGrid.clear();
    // set the grid size based on typical bounding box
    stationGrid.setGrid(bbox, typicalBB.getWidth(), typicalBB.getHeight());


    // always draw selected
    if (selected != null) {
      selected.calcPos( world2Normal);
      stationGrid.markIfClear( selected.getBB(), selected);
      selected.draw(g);
    } */

    g.setFont( textFont.getFont());
    g.setColor(color);

    int count = 0;
    int npts = obsUIlist.size();
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, npts);
    for (int i=0; i < npts; i++) {
      ObservationUI s = (ObservationUI) obsUIlist.get(i);
      s.calcPos(world2Normal);
      s.draw(g);

      if (Double.isNaN( s.screenPos.getX())) {
        System.out.println("screenPos="+s.screenPos+" world = "+s.worldPos);
        continue;
      }

      if (count == 0)
        path.moveTo( (float) s.screenPos.getX(), (float) s.screenPos.getY());
      else
        path.lineTo( (float) s.screenPos.getX(), (float) s.screenPos.getY());
      count++;
    }

    g.setColor(color);
    if (drawConnectingLine) 
      g.draw( path);

    // draw selected
    if (selected != null)
      selected.draw(g);

    // restore
    g.setTransform(world2Device);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, saveHint);
  }
/*
Find station that contains this point. If it exists, make it the
"selected" station.
@param pickPt: world coordinates
@return station that contains this point, or null if none.

public PointObsDatatype pick(Point2D pickPt) {
if (world2Normal == null || pickPt == null || obsUIlist.isEmpty()) return null;

world2Normal.transform(pickPt, ptN); // work in normalized coordinate space
ObservationUI closest = (ObservationUI) stationGrid.findIntersection(ptN);
setSelectedStation( closest);

return getSelectedStation();
}

/*
Find station closest to this point. Make it the "selected" station.
@param pickPt: world coordinates
@return station that contains this point, or null if none.

public PointObsDatatype pickClosest(Point2D pickPt) {
if (world2Normal == null || pickPt == null || obsUIlist.isEmpty()) return null;

world2Normal.transform(pickPt, ptN); // work in normalized coordinate space
ObservationUI closest = (ObservationUI) stationGrid.findClosest(ptN);

if (debug) System.out.println("closest= " +closest);
setSelectedStation( closest);

return getSelectedStation();
}


Get the selected station, or null.

public PointObsDatatype getSelectedStation() {
return (selected != null) ? selected.getObservation() : null;
}


Is this point contained in a Station bounding box?
@param p: normalized coords.
@return Station containing pt, or null.

public ObservationUI isOnStation( Point p) {
return (ObservationUI) stationGrid.findIntersection (p);
}