Finding the center (xy) of a OMText?

View: New views
5 Messages — Rating Filter:   Alert me  

Finding the center (xy) of a OMText?

by oland :: Rate this Message:

| View Threaded | Show Only this Message

Hello

I'm trying to implement clustering of locations a'la google maps marker clustering. But I'm having difficulties finding the exact center (xy) of the OMText which represents the clustering count. This causes a slight misalignment of the icons sitting behind the count.

Here is my code from generate:

        label.generate(proj);
        label.prepareForRender(g);
        if (label.getPolyBounds() != null) {
            Rectangle rect = label.getPolyBounds().getBounds();
            rh = (int) ((float) (bounds.getHeight() - currentFontDescent / 2));
            rw = (int) rect.getWidth();
            int width = raster.getImage().getWidth(null);
            int height = raster.getImage().getHeight(null);
            raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
            double cX = label.getMapLocation().getX() + rw / 2;
            double cY = label.getMapLocation().getY() + currentFontDescent / 2;
            raster.setX((int) (cX - width / 2));
            raster.setY((int) (cY - height / 2));

I tried with getCenterX/Y on getPolyBounds but the result varies with the font size and length of the string being rendered. It seems to work best with string length > 1.

I would like to use

FontMetrics metrics = g.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(text, g);

but I guess this does not work with OMText and the way it does text rendering.

Any hints?

Thanks
Carsten



Re: Finding the center (xy) of a OMText?

by Don Dietrick-2 :: Rate this Message:

| View Threaded | Show Only this Message

Hi Carsten,

Are you using center justification for the label?  If you draw the poly bounds (I think it shows if matting is turned on), do the bounds look right, even for one character?

I thought polybounds took font and size into account, but now that you mention it, I'm not sure if I've looked at it with one character, which seems to be quite pertinent to you.

- Don

On Thu, Oct 27, 2011 at 10:01 AM, "Carsten Ø. Madsen" <com@...> wrote:
Hello

I'm trying to implement clustering of locations a'la google maps marker clustering. But I'm having difficulties finding the exact center (xy) of the OMText which represents the clustering count. This causes a slight misalignment of the icons sitting behind the count.

Here is my code from generate:

        label.generate(proj);
        label.prepareForRender(g);
        if (label.getPolyBounds() != null) {
            Rectangle rect = label.getPolyBounds().getBounds();
            rh = (int) ((float) (bounds.getHeight() - currentFontDescent / 2));
            rw = (int) rect.getWidth();
            int width = raster.getImage().getWidth(null);
            int height = raster.getImage().getHeight(null);
            raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
            double cX = label.getMapLocation().getX() + rw / 2;
            double cY = label.getMapLocation().getY() + currentFontDescent / 2;
            raster.setX((int) (cX - width / 2));
            raster.setY((int) (cY - height / 2));

I tried with getCenterX/Y on getPolyBounds but the result varies with the font size and length of the string being rendered. It seems to work best with string length > 1.

I would like to use

FontMetrics metrics = g.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(text, g);

but I guess this does not work with OMText and the way it does text rendering.

Any hints?

Thanks
Carsten




Re: Finding the center (xy) of a OMText?

by oland :: Rate this Message:

| View Threaded | Show Only this Message

Hi Don

I got bitten by the fact that my location cluster is a BasicLocation which is implies that the OMText is decluttered so I had to do:

    @Override
    public boolean generate(Projection proj, DeclutterMatrix declutterMatrix) {
        return generate(proj);
    }

In the picture below the magenta rects are the center(s) of my calculation. It seems nearly correct for two digits but not for single digits.

                int height = g.getFontMetrics().getAscent();
                Rectangle2D strBounds = fm.getStringBounds(label.getData(), g);
                double cX = label.getMapLocation().getX()
                        + strBounds.getWidth() / 2;
                double cY = label.getMapLocation().getY() + ((height / 2) - 2);
                int w = 4;
                int h = 4;
                rec.setLocation((int) cX - w / 2, (int) cY - h / 2, (int) cX
                        + w / 2, (int) cY + h / 2);
                rec.setVisible(clustered);
                setLocationMarker(rec);

Is there anything else in Location/BasicLocation that alters the position of the OMText during generate?

BR
Carsten

On 10/28/2011 11:31 PM, Don Dietrick wrote:
Hi Carsten,

Are you using center justification for the label?  If you draw the poly bounds (I think it shows if matting is turned on), do the bounds look right, even for one character?

I thought polybounds took font and size into account, but now that you mention it, I'm not sure if I've looked at it with one character, which seems to be quite pertinent to you.

- Don

On Thu, Oct 27, 2011 at 10:01 AM, "Carsten Ø. Madsen" <com@...> wrote:
Hello

I'm trying to implement clustering of locations a'la google maps marker clustering. But I'm having difficulties finding the exact center (xy) of the OMText which represents the clustering count. This causes a slight misalignment of the icons sitting behind the count.

Here is my code from generate:

        label.generate(proj);
        label.prepareForRender(g);
        if (label.getPolyBounds() != null) {
            Rectangle rect = label.getPolyBounds().getBounds();
            rh = (int) ((float) (bounds.getHeight() - currentFontDescent / 2));
            rw = (int) rect.getWidth();
            int width = raster.getImage().getWidth(null);
            int height = raster.getImage().getHeight(null);
            raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
            double cX = label.getMapLocation().getX() + rw / 2;
            double cY = label.getMapLocation().getY() + currentFontDescent / 2;
            raster.setX((int) (cX - width / 2));
            raster.setY((int) (cY - height / 2));

I tried with getCenterX/Y on getPolyBounds but the result varies with the font size and length of the string being rendered. It seems to work best with string length > 1.

I would like to use

FontMetrics metrics = g.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(text, g);

but I guess this does not work with OMText and the way it does text rendering.

Any hints?

Thanks
Carsten





Re: Finding the center (xy) of a OMText?

by Don Dietrick-2 :: Rate this Message:

| View Threaded | Show Only this Message

Hi Carsten, 

Sorry for taking so long getting back to you, I've lost 
power at my house so I'm typing this on my phone.

If you don't have a declutter matrix in your application it 
shouldn't be affecting the position of the location objects. 
The Location objects and text would stay where you placed
them.  It looks like Java puts one-letter strings with center-justification 
at the same place as left-justification.  Seems like prepareForRender should
test for the boundary edge and slide the text placement over to the left
as necessary. It would be interesting to see if all odd-number length strings
are one half letter too much to the right, and if font choice plays a role in
this behavior. 

-- Don

On Oct 29, 2011, at 10:56 AM, "Carsten Ø. Madsen" <com@...> wrote:

Hi Don

I got bitten by the fact that my location cluster is a BasicLocation which is implies that the OMText is decluttered so I had to do:

    @Override
    public boolean generate(Projection proj, DeclutterMatrix declutterMatrix) {
        return generate(proj);
    }

In the picture below the magenta rects are the center(s) of my calculation. It seems nearly correct for two digits but not for single digits.

                int height = g.getFontMetrics().getAscent();
                Rectangle2D strBounds = fm.getStringBounds(label.getData(), g);
                double cX = label.getMapLocation().getX()
                        + strBounds.getWidth() / 2;
                double cY = label.getMapLocation().getY() + ((height / 2) - 2);
                int w = 4;
                int h = 4;
                rec.setLocation((int) cX - w / 2, (int) cY - h / 2, (int) cX
                        + w / 2, (int) cY + h / 2);
                rec.setVisible(clustered);
                setLocationMarker(rec);

Is there anything else in Location/BasicLocation that alters the position of the OMText during generate?
<cehedgfc.png>
BR
Carsten

On 10/28/2011 11:31 PM, Don Dietrick wrote:
Hi Carsten,

Are you using center justification for the label?  If you draw the poly bounds (I think it shows if matting is turned on), do the bounds look right, even for one character?

I thought polybounds took font and size into account, but now that you mention it, I'm not sure if I've looked at it with one character, which seems to be quite pertinent to you.

- Don

On Thu, Oct 27, 2011 at 10:01 AM, "Carsten Ø. Madsen" <com@...> wrote:
Hello

I'm trying to implement clustering of locations a'la google maps marker clustering. But I'm having difficulties finding the exact center (xy) of the OMText which represents the clustering count. This causes a slight misalignment of the icons sitting behind the count.

Here is my code from generate:

        label.generate(proj);
        label.prepareForRender(g);
        if (label.getPolyBounds() != null) {
            Rectangle rect = label.getPolyBounds().getBounds();
            rh = (int) ((float) (bounds.getHeight() - currentFontDescent / 2));
            rw = (int) rect.getWidth();
            int width = raster.getImage().getWidth(null);
            int height = raster.getImage().getHeight(null);
            raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
            double cX = label.getMapLocation().getX() + rw / 2;
            double cY = label.getMapLocation().getY() + currentFontDescent / 2;
            raster.setX((int) (cX - width / 2));
            raster.setY((int) (cY - height / 2));

I tried with getCenterX/Y on getPolyBounds but the result varies with the font size and length of the string being rendered. It seems to work best with string length > 1.

I would like to use

FontMetrics metrics = g.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(text, g);

but I guess this does not work with OMText and the way it does text rendering.

Any hints?

Thanks
Carsten
<mime-attachment.png>


Re: Finding the center (xy) of a OMText?

by oland :: Rate this Message:

| View Threaded | Show Only this Message

Hi Don

I changed to:

getLabel().setBaseline(OMText.BASELINE_MIDDLE);
getLabel().setJustify(OMText.JUSTIFY_LEFT);

I also tried this (http://explodingpixels.wordpress.com/2009/01/29/drawing-text-about-its-visual-center/) but with the fonts I'm currently using it does not seem to make a difference.

Here here is the generate code for the location cluster:

    public boolean generate(Projection proj) {
        boolean clustered = markers.size() < minClusterSize ? false : true;
        OMRaster raster = (OMRaster) getLocationMarker();
        raster.setVisible(clustered);
        getLabel().setVisible(clustered);
        setVisible(clustered);
        if (clustered) {
            ClusterStyle style = calculateCluster();
            raster.setImage(style.getImage());
            label.setFont(style.getFont());
            Coordinate centerCoords = getCenter();
            setLocation(centerCoords.y, centerCoords.x);
            getLabel().setBaseline(OMText.BASELINE_MIDDLE);
            getLabel().setJustify(OMText.JUSTIFY_LEFT);
            // getLabel().setShowBounds(true);
            getLabel().setData("" + markers.size());

            Graphics g = ...getGraphics();
            FontMetrics fm = null;
            if (g != null) {
                g.setFont(label.getFont());
                fm = g.getFontMetrics();             
            }

            label.generate(proj);
            label.prepareForRender(g);
            if (label.getPolyBounds() != null) {
                int width = raster.getImage().getWidth(null);
                int height = raster.getImage().getHeight(null);
                raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
                Rectangle2D strBounds = fm.getStringBounds(label.getData(), g);
                double cX = label.getMapLocation().getX()
                        + (strBounds.getWidth() / 2f);
                double cY = label.getMapLocation().getY() - 2;
                raster.setX((int) (cX - width / 2));
                raster.setY((int) (cY - height / 2));
                raster.generate(proj);
            }
        }
        return true;
    }

/carsten

On 11/01/2011 01:42 AM, Don Dietrick wrote:
Hi Carsten, 

Sorry for taking so long getting back to you, I've lost 
power at my house so I'm typing this on my phone.

If you don't have a declutter matrix in your application it 
shouldn't be affecting the position of the location objects.. 
The Location objects and text would stay where you placed
them.  It looks like Java puts one-letter strings with center-justification 
at the same place as left-justification.  Seems like prepareForRender should
test for the boundary edge and slide the text placement over to the left
as necessary. It would be interesting to see if all odd-number length strings
are one half letter too much to the right, and if font choice plays a role in
this behavior. 

-- Don

On Oct 29, 2011, at 10:56 AM, "Carsten Ø. Madsen" <com@...> wrote:

Hi Don

I got bitten by the fact that my location cluster is a BasicLocation which is implies that the OMText is decluttered so I had to do:

    @Override
    public boolean generate(Projection proj, DeclutterMatrix declutterMatrix) {
        return generate(proj);
    }

In the picture below the magenta rects are the center(s) of my calculation. It seems nearly correct for two digits but not for single digits.

                int height = g.getFontMetrics().getAscent();
                Rectangle2D strBounds = fm.getStringBounds(label.getData(), g);
                double cX = label.getMapLocation().getX()
                        + strBounds.getWidth() / 2;
                double cY = label.getMapLocation().getY() + ((height / 2) - 2);
                int w = 4;
                int h = 4;
                rec.setLocation((int) cX - w / 2, (int) cY - h / 2, (int) cX
                        + w / 2, (int) cY + h / 2);
                rec.setVisible(clustered);
                setLocationMarker(rec);

Is there anything else in Location/BasicLocation that alters the position of the OMText during generate?
<cehedgfc.png>
BR
Carsten

On 10/28/2011 11:31 PM, Don Dietrick wrote:
Hi Carsten,

Are you using center justification for the label?  If you draw the poly bounds (I think it shows if matting is turned on), do the bounds look right, even for one character?

I thought polybounds took font and size into account, but now that you mention it, I'm not sure if I've looked at it with one character, which seems to be quite pertinent to you.

- Don

On Thu, Oct 27, 2011 at 10:01 AM, "Carsten Ø. Madsen" <com@...> wrote:
Hello

I'm trying to implement clustering of locations a'la google maps marker clustering. But I'm having difficulties finding the exact center (xy) of the OMText which represents the clustering count. This causes a slight misalignment of the icons sitting behind the count.

Here is my code from generate:

        label.generate(proj);
        label.prepareForRender(g);
        if (label.getPolyBounds() != null) {
            Rectangle rect = label.getPolyBounds().getBounds();
            rh = (int) ((float) (bounds.getHeight() - currentFontDescent / 2));
            rw = (int) rect.getWidth();
            int width = raster.getImage().getWidth(null);
            int height = raster.getImage().getHeight(null);
            raster.setRenderType(OMGraphicConstants.RENDERTYPE_XY);
            double cX = label.getMapLocation().getX() + rw / 2;
            double cY = label.getMapLocation().getY() + currentFontDescent / 2;
            raster.setX((int) (cX - width / 2));
            raster.setY((int) (cY - height / 2));

I tried with getCenterX/Y on getPolyBounds but the result varies with the font size and length of the string being rendered. It seems to work best with string length > 1.

I would like to use

FontMetrics metrics = g.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(text, g);

but I guess this does not work with OMText and the way it does text rendering.

Any hints?

Thanks
Carsten
<mime-attachment.png>