[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>
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.


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