Invalid images on area's border

classic Classic list List threaded Threaded
12 messages Options
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Invalid images on area's border

Hi,

I have the following problem when creating imagery by osgEarth. I have my own TMS source which serves image files (on many zoom levels) for my area of interest, but returns HTTP 404 for requests where no tile can be served. This leads to some artefacts, in which some fragments (sometimes large) are covered by images from lower zoom level, like in this example:



When I tried to solve this problem, I saw in osgEarth source code (osgEarth 1.3, MapLayer.cpp, line 552) that if any of the source tiles, which are required to create a tile by osgEarth, are missing, then no image is returned and no higher zoom level may be loaded. Therefore, when I have a tile on border of my area, on higher zoom level, and osgEarth tries to connect it with a non-existing tile, my tile is not displayed. What is important, when my server returned a transparent tile for non-existing tiles (instead of 404), it worked fine.

Could you suggest any solution for my problem? The only idea which comes to my mind is to create my own patch in osgEarth code to change the default behaviour when an intersecting tile cannot be loaded (or returning transparent tiles again, but this is something what I don't want to do).

Best regards,
Slawek
jasonbeverage jasonbeverage
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hi Slawek,

It makes sense to not require that a source has complete coverage to be able to do compositing.  If you simply comment out the bit of code on line 552 in MapLayer that returns 0 if a tile can't be retrieved do things work fine for you?

Thanks,

Jason

On Tue, Jul 6, 2010 at 10:25 AM, slawowski [via osgEarth] <[hidden email]> wrote:
Hi,

I have the following problem when creating imagery by osgEarth. I have my own TMS source which serves image files (on many zoom levels) for my area of interest, but returns HTTP 404 for requests where no tile can be served. This leads to some artefacts, in which some fragments (sometimes large) are covered by images from lower zoom level, like in this example:



When I tried to solve this problem, I saw in osgEarth source code (osgEarth 1.3, MapLayer.cpp, line 552) that if any of the source tiles, which are required to create a tile by osgEarth, are missing, then no image is returned and no higher zoom level may be loaded. Therefore, when I have a tile on border of my area, on higher zoom level, and osgEarth tries to connect it with a non-existing tile, my tile is not displayed. What is important, when my server returned a transparent tile for non-existing tiles (instead of 404), it worked fine.

Could you suggest any solution for my problem? The only idea which comes to my mind is to create my own patch in osgEarth code to change the default behaviour when an intersecting tile cannot be loaded (or returning transparent tiles again, but this is something what I don't want to do).

Best regards,
Slawek


View message @ http://forum.osgearth.org/Invalid-images-on-area-s-border-tp5260597p5260597.html
To start a new topic under osgEarth, email [hidden email]
To unsubscribe from osgEarth, click here.


slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Commenting out line 552 did not helped. Instead of this, I tried to add empty image (ImageUtils::getEmptyImage) to the list. This worked better, but still some artefacts occurred, especially my layer disappeared when being to close to the earth, when no tiles at this level were available - so this is not a solution for me.

Slawek
jasonbeverage jasonbeverage
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hi Slawek,

The image tile compositing code assumes that all the tiles are the
same size which is probably why adding the result of getEmptyImage,
which is a 1x1 transparent image, didn't work out for you.  Try
creating a transparent RGBA image that is the same size as all the
other tiles and see if that helps instead.

If you create a patch that fixes your issue we'll be happy to merge it.

Jason

On Wed, Jul 7, 2010 at 9:22 AM, slawowski [via osgEarth]
<[hidden email]> wrote:

> Commenting out line 552 did not helped. Instead of this, I tried to add
> empty image (ImageUtils::getEmptyImage) to the list. This worked better, but
> still some artefacts occurred, especially my layer disappeared when being to
> close to the earth, when no tiles at this level were available - so this is
> not a solution for me.
>
> Slawek
>
> ________________________________
> View message @
> http://forum.osgearth.org/Invalid-images-on-area-s-border-tp5260597p5265190.html
> To start a new topic under osgEarth, email
> [hidden email]
> To unsubscribe from osgEarth, click here.
>
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Thank you for your suggestion, this approach works fine for me. I replaced lines 535-554 in MapLayer.cpp in osgEarth 1.3 with the following lines:

                        osg::ref_ptr<MultiImage> mi = new MultiImage;
                        std::vector< osg::ref_ptr<const TileKey> > missingTiles;
                        for (unsigned int j = 0; j < intersectingTiles.size(); ++j)
                        {
                                double minX, minY, maxX, maxY;
                                intersectingTiles[j]->getGeoExtent().getBounds(minX, minY, maxX, maxY);

                                //osg::notify(osg::NOTICE) << "\t Intersecting Tile " << j << ": " << minX << ", " << minY << ", " << maxX << ", " << maxY << std::endl;

                                osg::ref_ptr<osg::Image> img = createImageWrapper(intersectingTiles[j].get(), cacheInLayerProfile, progress);
                                if (img.valid())
                                {
                                        mi->getImages().push_back(TileImage(img.get(), intersectingTiles[j].get()));
                                }
                                else
                                {
                                        osg::notify(osg::INFO) << "Couldn't create image for MultiImage " << std::endl;
                                        missingTiles.push_back(intersectingTiles[j].get());
                                }
                        }
                        if (intersectingTiles.size() > 0)
                        {
                                if (mi->getImages().empty())
                                {
                                        return 0;
                                }
                                else
                                {
                                        osg::ref_ptr<osg::Image> validImage = mi->getImages()[0].getImage();
                                        unsigned int tileWidth = validImage->s();
                                        unsigned int tileHeight = validImage->t();

                                        for (unsigned int j = 0; j < missingTiles.size(); ++j)
                                        {
                                                // Create transparent image which size equals to the size of a valid image
                                                osg::ref_ptr<osg::Image> newImage = new osg::Image;
                                                newImage->allocateImage(tileWidth, tileHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE);
                                                unsigned char *data = newImage->data(0,0);
                                                memset(data, 0, 4 * tileWidth * tileHeight);

                                                mi->getImages().push_back(TileImage(newImage.get(), missingTiles[j].get()));
                                        }
                                }
                        }


If you want, please review it and you can modify it and merge it.

However, this patch solved my problem only partially. If I have a tile on zoom level n and only one of four tiles on zoom level n+1, then no image is created for three other tiles on level n+1 and tile from level n is visible for all levels greater than n, which doesn't look nice. But this problem is probably a feature for other users, so I plan to prepare a patch, but I don't know whether it would be useful for others. I also noticed some changes in createSubTiles method in MapEngine in trunk, but I'm not sure whether it could solve my second problem?
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Unfortunately, I noticed also strange effects with JPEG layer when using the patch I posted. Probably the image format is different and transparent pixels do not integrate well. I will try to solve this issue.
jasonbeverage jasonbeverage
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hi Slawek,

If you can make the changes and test against the osgEarth trunk that
would help quite a bit.  Also, the changes you mentioned in
createSubTiles should fix the issue you mentioned before about the
tiles not subdividing as well.

Thanks,

Jason

On Thu, Jul 8, 2010 at 10:18 AM, slawowski [via osgEarth]
<[hidden email]> wrote:

> Unfortunately, I noticed also strange effects with JPEG layer when using the
> patch I posted. Probably the image format is different and transparent
> pixels do not integrate well. I will try to solve this issue.
>
> ________________________________
> View message @
> http://forum.osgearth.org/Invalid-images-on-area-s-border-tp5260597p5270318.html
> To start a new topic under osgEarth, email
> [hidden email]
> To unsubscribe from osgEarth, click here.
>
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Changes in createSubTiles did not fix my problem. However, I see that this issue cannot be solved on the tile engine level, because for satellite layer I want to display tiles from lower zoom level, if there is no higher one, while for layers with drawings and text it would be better not to enlarge the tiles from lower zoom levels. Therefore, I see that I will have to modify my data source to avoid the effect I'm watching.

But coming back to the first issue, I modified my patch to follow pixel format of the layer. Unfortunately, for JPEG layers this generates big black areas, which do not disappear when zooming in. Could you suggest any solution for merging JPEG tiles with transparent areas? The best solution I see now is to apply my patch only for layers which pixel format is GL_RGBA and skip JPEGs.
jasonbeverage jasonbeverage
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hi Slawek,

If you have JPEG imagery you could convert it to RGBA imagery before
performing the compositing.  There is a ImageUtils::convertToRGB
function that converts RGBA to RGB, you could write a similar function
to convert RGB to RGBA.  One thing you might need to be careful of is
caching the result to a non-rgba format like JPEG though.

Thanks,

Jason

On Fri, Jul 9, 2010 at 8:36 AM, slawowski [via osgEarth]
<[hidden email]> wrote:

> Changes in createSubTiles did not fix my problem. However, I see that this
> issue cannot be solved on the tile engine level, because for satellite layer
> I want to display tiles from lower zoom level, if there is no higher one,
> while for layers with drawings and text it would be better not to enlarge
> the tiles from lower zoom levels. Therefore, I see that I will have to
> modify my data source to avoid the effect I'm watching.
>
> But coming back to the first issue, I modified my patch to follow pixel
> format of the layer. Unfortunately, for JPEG layers this generates big black
> areas, which do not disappear when zooming in. Could you suggest any
> solution for merging JPEG tiles with transparent areas? The best solution I
> see now is to apply my patch only for layers which pixel format is GL_RGBA
> and skip JPEGs.
>
> ________________________________
> View message @
> http://forum.osgearth.org/Invalid-images-on-area-s-border-tp5260597p5274090.html
> To start a new topic under osgEarth, email
> [hidden email]
> To unsubscribe from osgEarth, click here.
>
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hi Jason,

I prepared convertToRGBA function in ImageUtils and now it works with JPEGs. I hope that tiles are still cached in JPEGs, because call of createImageWrapper is before my conversion.

I attached the files I modified (from trunk version). If you want, you can test it and merge it or do whatever you want with it.

ImageUtils
ImageUtils.cpp
MapLayer.cpp

Slawek
slawowski slawowski
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

New version of patch for MapLayer - it handles tiles in different formats better.

MapLayer.cpp

Slawek
jasonbeverage jasonbeverage
Reply | Threaded
Open this post in threaded view
|

Re: Invalid images on area's border

Hey Slawek,

Your changes look good to me, merged with the trunk.

Thanks!

Jason

On Thu, Jul 29, 2010 at 9:00 AM, slawowski [via osgEarth]
<[hidden email]> wrote:

> New version of patch for MapLayer - it handles tiles in different formats
> better.
>
> MapLayer.cpp
>
> Slawek
>
> ________________________________
> View message @
> http://forum.osgearth.org/Invalid-images-on-area-s-border-tp5260597p5347284.html
> To start a new topic under osgEarth, email
> [hidden email]
> To unsubscribe from osgEarth, click here.
>