[OSM-dev] Trial clickable POI layer
David Earl
david at frankieandshadow.com
Fri Sep 21 19:23:11 BST 2007
OK, a bit more detail for what I'd do if I were doing it...
The tile cache stuff is independent from the stylesheet bit.
Generate an HTML file representing all POIs within the area of each tile
at each zoom. This is the equivalent of a "tile". I'm guessing this
isn't all that much different from what you're doing dynamically now.
But I really think it does need saving: there must be more than 60,000
POIs - unless you are only thinking about specific types, maybe. But
given the HTML is very compact, I think all POIs per tile could be done.
This could be done in response to a tile render request to mapnik, or
when viewing as you're doing now but cache the result to avoid repeated
server requests. Have the openlayers layer fetch the html file, which
can be numbered in the same way as the image tiles.
Each POI in the HTML could simply be:
<div class='C' style='top:Xpx;left:Ypx;'>T</div>
where C is the object type (class='station','church','school','pub'...,
or maybe choose c1, c2, ... as names for compactness - so long as they
correspond to the style sheet, and there is a mapping to hunman readable
text for the user interface it doesn't matter what they are called) and
T is any text associated with the POI. x and y are the pixel coordinates
of the object. This will generate nicely compact HTML. Note this doesn't
say anything about what it looks like at all, but does give a position
relative to the tile. [CSS: The idea is that the browser then determines
the visual appearance of the elements by looking up rules for the class
name 'C' in the stylesheet (which can be in a separate file, but doesn't
have to be)].
Then the CSS stylesheet would have
div.station {
... style properties for a station ...
}
etc. All classes would have
position: absolute;
to have the top and left take effect correctly and allow overlapping
etc. This can be done in a single rule: if all your div's are enclosed
in a parent div
<div class='pois'>
<div class='church'>...</div>
...
</div>
then the single CSS rule
div.pois div.* {
position: absolute;
}
would do it IIRC.
The icon would be provided by the stylesheet property background-image:
div.church {
background-image: url(...);
background-repeat: no-repeat;
}
so the icon comes from the stylesheet, not embedded in the HTML. If
there is an icon, there would also need to have padding properties
dependent on the icon size to offset the text within the div box so it
doesn't overlap the icon.
If the HTML has a second class
<div class='a1 c1'>...
then the 'a's can control some generic properties like text size and so
on for a whole class of classes.
Javascript can then modify the style of particular classes to set the
display property to make it invisible (display:none) or not
(display:block), or change other properties dynamically, in response to
use controls. Note that this is editing the stylesheet, not the style
properties of individual elements. This means as you pan and new
elements come into view, they don't need to be modified to reflect the
users settings: this will be automatic. Editing stylesheets in JS is a
bit fiddly; alternatively the settings could be individually applied to
each, with a trigger on drag to update.
The user control could also be generated dynamically: each class in the
stylesheet could generate a checkbox in Javascript.
Once a mechanism like this is in place, the appearance of each object is
enormously flexible. If we started with on/off and maybe text sizes, I'm
sure lots of new stuff would come along. We'd need to persuade Artem to
turn off POI text rendering at some stage.
David
On 21/09/2007 18:43, Martijn van Oosterhout wrote:
> On 9/21/07, David Earl <david at frankieandshadow.com> wrote:
>> I think it is going to need separate "tiles" at each zoom level so the
>> amount of data can be throttled (I assume this isn't going to the
>> database for each overlay, but pre-generating them like the image tiles
>> do, yes? If not, I think they should be - essentially they are companion
>> data to the image tiles so can sit alongside the image tiles).
>
> No, these arn't tiles. This is just a DB serving data asked for.
> Basically depending on where you are the client requests a bbox and
> the server gives it a list of POIs. I don't really want to go down the
> route of making tiles of them, the data (currently only 60,000 POIs)
> just isn't enough to justify it.
>
> So when you load the map there is only *one* request to the server, no
> matter what zoom-level you're on. And you need to pan quite a bit to
> trigger a new request.
>
>> I suggest the "horizontal" text (names of POIs, place names etc) is also
>> in these "tiles" (maybe a separate layer, I don't know what layers can
>> hold, but if it is html, it can be both simultaneously).
>
> You mean display the names always? Without clicking on anything?
>
>> I would also put _all_ the POIs (determined as useful for that zoom
>> level) on one layer (two layers with text if necessary), but give them
>> an HTML class; then have a control dialogue somewhere which allows the
>> user to turn on and off the icons/text for particular classes of POI.
>
> I like the class idea. I have prectically no experience with
> stylesheets, but the possiblities are there. Do you have some idea of
> what kind of things we want to be selectable?
>
> Have a nice day,
More information about the dev
mailing list