C
Charles Packer
Here's a graphics problem, the solution to which is conceptually simple.
The goal is to speed up the refreshing of a map after changing the
geographic vector data from which it is developed. What's obscure to me
is how to go from the ingredients provided in the Java API to an actual
recipe.
In an application that displays a map with overlays of different types
of data as individual layers -- state boundaries, airports, flight tracks
of aircraft, etc. we want to be able to change the data in a layer or turn
one off or on without having to redraw all the layers each time. From a Google
search of Java newsgroups I see that related forms of this question have
come up before, but with no decisive answers (in several instances, no
followups at all). Therefore I've expended extra effort in this rather
lengthy query to try to be clear about what the issues are.
We're using an open source product, OpenMap, that takes several seconds
to do this redrawing of all the layers. When a user does a pan or a zoom,
OR makes a change to the data in any one layer, OpenMap cycles through
all the active layers. Each layer extends JComponent and overrides the
"paint" method to draw its data into the graphics context. Layer order
can be chosen by the user such that layers showing opaque things, like
countries and water, are drawn first, and then lines and points of interest
are drawn last. For a pan or a zoom, of course, the positions of all these
have to be recomputed first, but the amount of time that this computation takes
is _insignificant_ compared to the paint operation.
Note that the parameterized paint method, for restricting drawing to a subset
of the window, is of little use here, since typically the data of interest
in any one layer are scattered all over the map.
From a Java tip page I learned that I could override "update" instead of
paint for incremental drawing, and this would avoid repaintng the whole
window. However, I discovered that this method wasn't even called (!) when I
coded an override of it in my test class.
Conceptually, what I want to do is this: Draw the data vector of each layer
to its own invisible pixel buffer. Then, where I actually want to see the
contents of one or more layers, combine them quickly into one visible image.
Given that each layer's pixel buffer has identical dimensions and covers the
same geographic area, the combining would involve simple pixel-by-pixel
overlay logic. For example, to turn off one of the layers, simply refresh
the visible image with all the pixel buffers of all the layers _except_ the
one I want to turn off.
I'm disappointed that Java hasn't solved the problem I had with Motif in
another life: there's a Grand Disconnect between drawing vectors and pixel
images. I can create a line by a drawing operation into a graphics
"context", which is...well, whatever it is, once my line is drawn, I can't
change its color...I can't do anything to it; it may be visible...but it's
out of reach. I can't save it as pixels and simply flip it back to the
screen later without redrawing it. On the other hand, I can create an array
that can become a pixel image...but how do I get a line into it in the first
place? Answer: I have to reinvent the wheel and write a drawing routine. Or
so it seems...where's the bridge between these two domains?
The goal is to speed up the refreshing of a map after changing the
geographic vector data from which it is developed. What's obscure to me
is how to go from the ingredients provided in the Java API to an actual
recipe.
In an application that displays a map with overlays of different types
of data as individual layers -- state boundaries, airports, flight tracks
of aircraft, etc. we want to be able to change the data in a layer or turn
one off or on without having to redraw all the layers each time. From a Google
search of Java newsgroups I see that related forms of this question have
come up before, but with no decisive answers (in several instances, no
followups at all). Therefore I've expended extra effort in this rather
lengthy query to try to be clear about what the issues are.
We're using an open source product, OpenMap, that takes several seconds
to do this redrawing of all the layers. When a user does a pan or a zoom,
OR makes a change to the data in any one layer, OpenMap cycles through
all the active layers. Each layer extends JComponent and overrides the
"paint" method to draw its data into the graphics context. Layer order
can be chosen by the user such that layers showing opaque things, like
countries and water, are drawn first, and then lines and points of interest
are drawn last. For a pan or a zoom, of course, the positions of all these
have to be recomputed first, but the amount of time that this computation takes
is _insignificant_ compared to the paint operation.
Note that the parameterized paint method, for restricting drawing to a subset
of the window, is of little use here, since typically the data of interest
in any one layer are scattered all over the map.
From a Java tip page I learned that I could override "update" instead of
paint for incremental drawing, and this would avoid repaintng the whole
window. However, I discovered that this method wasn't even called (!) when I
coded an override of it in my test class.
Conceptually, what I want to do is this: Draw the data vector of each layer
to its own invisible pixel buffer. Then, where I actually want to see the
contents of one or more layers, combine them quickly into one visible image.
Given that each layer's pixel buffer has identical dimensions and covers the
same geographic area, the combining would involve simple pixel-by-pixel
overlay logic. For example, to turn off one of the layers, simply refresh
the visible image with all the pixel buffers of all the layers _except_ the
one I want to turn off.
I'm disappointed that Java hasn't solved the problem I had with Motif in
another life: there's a Grand Disconnect between drawing vectors and pixel
images. I can create a line by a drawing operation into a graphics
"context", which is...well, whatever it is, once my line is drawn, I can't
change its color...I can't do anything to it; it may be visible...but it's
out of reach. I can't save it as pixels and simply flip it back to the
screen later without redrawing it. On the other hand, I can create an array
that can become a pixel image...but how do I get a line into it in the first
place? Answer: I have to reinvent the wheel and write a drawing routine. Or
so it seems...where's the bridge between these two domains?