[Geoserver-devel] default missing image for broken external graphics

Hey there,

I’ve had a request to implement some better support for broken ExternalGraphic instances. At the moment, if a URL is broken (whatever the cause, no image), there is no great notification of this problem. The logs will contain messages like (one for each feature, ugh):

ERROR [lite.StyledShapePainter] - ShapePainter has been asked to paint a null style!!

One way to ‘work around’ this is to include a second ExternalGraphic in one’s SLD but this is not acceptable to me.

How does the idea of a ‘missing graphic’ feel? Like a simple icon or symbol with coloring to set it off? I made a very ugly ‘?’ ttf mark with green and red as a test but would settle for anything really :slight_smile:

How about some type of per-request (not per-feature as it is now) logging about the specific missing URL? It’s possible to change log levels to help debug this but it can result in overwhelming output and does nothing to help detect this issue earlier (like a ‘missing’ icon or succinct log message might).

Another issue is that the renderer will continue to attempt to resolve the bad URL, once for each feature, resulting in annoying web traffic for both parties.

Any thoughts?

Ian Schneider
Software Engineer | Boundless
ischneider@anonymised.com

We kind of have an answer for this one, when you define a mark you get to define a list of options. Starting with SVG, moving on to PNG, and finally a well known mark.

The idea is the system is supposed to “Fall back” to the next one in the list if it is unable to render (or find?) the external graphic.

So before putting a lot more work into this try adding a well known mark to your list.

···

Jody Garnett

On Wed, Jun 11, 2014 at 5:50 AM, Ian Schneider <ischneider@anonymised.com> wrote:

Hey there,

I’ve had a request to implement some better support for broken ExternalGraphic instances. At the moment, if a URL is broken (whatever the cause, no image), there is no great notification of this problem. The logs will contain messages like (one for each feature, ugh):

ERROR [lite.StyledShapePainter] - ShapePainter has been asked to paint a null style!!

One way to ‘work around’ this is to include a second ExternalGraphic in one’s SLD but this is not acceptable to me.

How does the idea of a ‘missing graphic’ feel? Like a simple icon or symbol with coloring to set it off? I made a very ugly ‘?’ ttf mark with green and red as a test but would settle for anything really :slight_smile:

How about some type of per-request (not per-feature as it is now) logging about the specific missing URL? It’s possible to change log levels to help debug this but it can result in overwhelming output and does nothing to help detect this issue earlier (like a ‘missing’ icon or succinct log message might).

Another issue is that the renderer will continue to attempt to resolve the bad URL, once for each feature, resulting in annoying web traffic for both parties.

Any thoughts?

Ian Schneider
Software Engineer | Boundless
ischneider@anonymised.com


HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

Sorry Ian I misunderstood, you are aware of the second well-known-graphic trick already.

Most of the fixes I can think of are at the GeoTools level:

  1. Generic GeoTools fix

In SLDStyleFactory getIcon method where most of the magic is happening, we could add a “blacklist” here of known external graphics that were unable to be found, and return a placeholder graphic.

  1. GeoServer ExternalGraphicFactory fix

A non invasive change we could do from GeoServer is create our own BlackListGraphicFactory that accepts any external graphic request and returns the placeholder “broken” image. The only trick here would be to arrange the factory sort order so this factory is checked “last” …

  1. Specific ImageGraphicFactory fix

The ImageGraphicFactory maintains its own cache (static final). We could teach it to note what images could not be found and return a placeholder. We can also store the placeholder in the cache resulting in a relatively easy to implement blacklist.

Option 3 is quickest to implement, Option 1 handles both PNG and SVG.

···

Jody Garnett

On Wed, Jun 11, 2014 at 5:50 AM, Ian Schneider <ischneider@anonymised.com> wrote:

Hey there,

I’ve had a request to implement some better support for broken ExternalGraphic instances. At the moment, if a URL is broken (whatever the cause, no image), there is no great notification of this problem. The logs will contain messages like (one for each feature, ugh):

ERROR [lite.StyledShapePainter] - ShapePainter has been asked to paint a null style!!

One way to ‘work around’ this is to include a second ExternalGraphic in one’s SLD but this is not acceptable to me.

How does the idea of a ‘missing graphic’ feel? Like a simple icon or symbol with coloring to set it off? I made a very ugly ‘?’ ttf mark with green and red as a test but would settle for anything really :slight_smile:

How about some type of per-request (not per-feature as it is now) logging about the specific missing URL? It’s possible to change log levels to help debug this but it can result in overwhelming output and does nothing to help detect this issue earlier (like a ‘missing’ icon or succinct log message might).

Another issue is that the renderer will continue to attempt to resolve the bad URL, once for each feature, resulting in annoying web traffic for both parties.

Any thoughts?

Ian Schneider
Software Engineer | Boundless
ischneider@anonymised.com


HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

On Wed, Jun 11, 2014 at 9:08 AM, Jody Garnett <jody.garnett@anonymised.com>
wrote:

Sorry Ian I misunderstood, you are aware of the second well-known-graphic
trick already.

Most of the fixes I can think of are at the GeoTools level:

1) Generic GeoTools fix

In SLDStyleFactory getIcon method where most of the magic is happening, we
could add a "blacklist" here of known external graphics that were unable to
be found, and return a placeholder graphic.

2) GeoServer ExternalGraphicFactory fix

A non invasive change we could do from GeoServer is create our own BlackListGraphicFactory
that accepts any external graphic request and returns the placeholder
"broken" image. The only trick here would be to arrange the factory sort
order so this factory is checked "last" ...

3) Specific ImageGraphicFactory fix

The ImageGraphicFactory maintains its own cache (static final). We could
teach it to note what images could not be found and return a placeholder.
We can also store the placeholder in the cache resulting in a relatively
easy to implement blacklist.

Option 3 is quickest to implement, Option 1 handles both PNG and SVG.

Hi,
chiming in late, sorry.
Option 3 is no go, it will break the SLD mandated fallback mechanism, if
you have more than one graphic you need to fall back to the next one until
all possibilities are exhausted.
Option 2 would similarly not work, because it would break falling back to
marks

Option 1 is the only real option imho, once you tried _everything_ that was
in the SLD, fell back and found no options, using a mark (because it can be
rescaled) that gives the idea of an error
would be probably a good option.
Again, not sure if we are going to break the compatibility with the SLD
spec doing that, so maybe check, and in case, add a flag of sorts to
control it.
Adding a good ERROR or WARNING level logging stating that we tried all the
graphics and none worked would be probably good.

Cheers
Andrea

--

GeoServer Professional Services from the experts! Visit
http://goo.gl/NWWaa2 for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------

Thanks for the feedback, reply below

···

On Wed, Jun 11, 2014 at 10:28 AM, Andrea Aime <andrea.aime@anonymised.com> wrote:

Agreed option 1 seems like the best approach.

As for the spec, my reading doesn’t provide much about a ‘default’ fallback or even whether this should be drawn or reported as an exception. I tried MapServer[1] to see what it would do and for both se_xml and se_inimage I got exception reports (no better in quality…) but no default mark.

The implementation I came up with renders a question mark using the ttf specifier and makes a better, single log message. I’m not too happy with the way the mark looks, however and I’m thinking a more ‘standard’ (if there is such a thing) missing image icon would be better. I suppose this could be included and referenced via a jar URL?

Ian Schneider
Software Engineer | Boundless
ischneider@anonymised.com

On Wed, Jun 11, 2014 at 9:08 AM, Jody Garnett <jody.garnett@anonymised.com03…> wrote:

Sorry Ian I misunderstood, you are aware of the second well-known-graphic trick already.

Most of the fixes I can think of are at the GeoTools level:

  1. Generic GeoTools fix

In SLDStyleFactory getIcon method where most of the magic is happening, we could add a “blacklist” here of known external graphics that were unable to be found, and return a placeholder graphic.

  1. GeoServer ExternalGraphicFactory fixreadImage(): General error message. unsupported pixmap format

A non invasive change we could do from GeoServer is create our own BlackListGraphicFactory that accepts any external graphic request and returns the placeholder “broken” image. The only trick here would be to arrange the factory sort order so this factory is checked “last” …

  1. Specific ImageGraphicFactory fix

The ImageGraphicFactory maintains its own cache (static final). We could teach it to note what images could not be found and return a placeholder. We can also store the placeholder in the cache resulting in a relatively easy to implement blacklist.

Option 3 is quickest to implement, Option 1 handles both PNG and SVG.

Hi,
chiming in late, sorry.
Option 3 is no go, it will break the SLD mandated fallback mechanism, if you have more than one graphic you need to fall back to the next one until all possibilities are exhausted.
Option 2 would similarly not work, because it would break falling back to marks

Option 1 is the only real option imho, once you tried everything that was in the SLD, fell back and found no options, using a mark (because it can be rescaled) that gives the idea of an error
would be probably a good option.
Again, not sure if we are going to break the compatibility with the SLD spec doing that, so maybe check, and in case, add a flag of sorts to control it.
Adding a good ERROR or WARNING level logging stating that we tried all the graphics and none worked would be probably good.

On Fri, Jun 13, 2014 at 6:28 PM, Ian Schneider <ischneider@anonymised.com>
wrote:

The implementation I came up with renders a question mark using the ttf
specifier and makes a better, single log message. I'm not too happy with
the way the mark looks, however and I'm thinking a more 'standard' (if
there is such a thing) missing image icon would be better. I suppose this
could be included and referenced via a jar URL?

Hmm... the TTF font you are using would have to be part of the renderer
jar, there is no standard java font available on all jdks.

Anyways, reading the spec, there are some clues of what we migth do:

"If the Graphic element is omitted from the parent element, then nothing
will be plotted"

"The default if neither an ExternalGraphic nor a Mark is specified is to
use the default
mark of a “square” with a 50%-gray fill and a black outline, with a size of
6 pixels,"

So, what if we have a Graphic, but none of the various external graphics in
it works?
Given that the normal behavior is to ignore the ones that are not working
and move on,
I'd say the behavior closest to the spec suggestions is to act as if no
external graphic
nor mark was provided, and do the 50% gray fill and black outline 6px
square?

Cheers
Andrea

--

GeoServer Professional Services from the experts! Visit
http://goo.gl/NWWaa2 for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------

On Fri, Jun 13, 2014 at 10:36 AM, Andrea Aime <andrea.aime@anonymised.com>
wrote:

On Fri, Jun 13, 2014 at 6:28 PM, Ian Schneider <
ischneider@anonymised.com> wrote:

The implementation I came up with renders a question mark using the ttf
specifier and makes a better, single log message. I'm not too happy with
the way the mark looks, however and I'm thinking a more 'standard' (if
there is such a thing) missing image icon would be better. I suppose this
could be included and referenced via a jar URL?

Hmm... the TTF font you are using would have to be part of the renderer
jar, there is no standard java font available on all jdks.

This crossed my mind, so I used ttf://SansSerif#0x003F as I understood this
'logical font' will be guaranteed to map to some font.

Anyways, reading the spec, there are some clues of what we migth do:

"If the Graphic element is omitted from the parent element, then nothing
will be plotted"

"The default if neither an ExternalGraphic nor a Mark is specified is to
use the default
mark of a “square” with a 50%-gray fill and a black outline, with a size
of 6 pixels,"

Thanks for seeing that - I missed it.

So, what if we have a Graphic, but none of the various external graphics
in it works?
Given that the normal behavior is to ignore the ones that are not working
and move on,
I'd say the behavior closest to the spec suggestions is to act as if no
external graphic
nor mark was provided, and do the 50% gray fill and black outline 6px
square?

Makes sense to me and seems inline with the intentions of the spec.

--
Ian Schneider
Software Engineer | Boundless
ischneider@anonymised.com