Search code examples
javascripthtmlopenlayers

Display POIs using OpenLayers without a text file


I need to display markers with information on a slippy map using OpenLayers. An example of what I'm attempting to do can be seen here:http://wiki.openstreetmap.org/wiki/Openlayers_POI_layer_example

Due to the inflexible nature of the software product I'm using, I cannot use server side scripting and I can't access the information I need from my SQL database directly.

What I can do, is get the information from the SQL database and read it into an html table, after which I can parse that table into a javascript array. The problem is that OpenLayers.Layer.Text requires a text file, so how do I get the information from the javascript array into a format that OpenLayers can use to display the information next to each marker?

Additional Code

Here's my attempt to use vectors to solve the problem. Unfortunately this code doesn't seem to work - I've checked it and it seems fine. Any ideas?

<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">

    var osmap = null;
    var wgs84Proj = null;
    var osmapProj = null;

    function initialise() 
    {
        var elmnts = document.getElementById('data').getElementsByTagName('tr');
        var ACol = -1;
        var BCol = -1;
        var CCol = -1;      
        var LonCol = -1;
        var LatCol = -1;
        var minX = 0;
        var maxX = 0;
    var minY = 0;
    var maxY = 0;

    // Match fields to column headings in first row
    for (var col=0; col < elmnts[0].cells.length; col++) 
    {
        var val = elmnts[0].cells[col].innerHTML;
        switch (val) 
        {
            case "A": ACol = col; break;
            case "B": BCol = col; break;
            case "C": CCol = col; break;                
            case "LON": LonCol = col; break;
            case "LAT": LatCol = col; break;
            default:
        }
    }

    // Initialise bounding coordinates
    if (elmnts.length > 1) 
    {
        minX = Number(elmnts[1].cells[LonCol].innerHTML) - 0.00001
        maxX = Number(elmnts[1].cells[LonCol].innerHTML) + 0.00001
        minY = Number(elmnts[1].cells[LatCol].innerHTML) - 0.00001
        maxY = Number(elmnts[1].cells[LatCol].innerHTML) + 0.00001
    }

    osmap = new OpenLayers.Map
    (
        {
            div: "map_canvas",
            controls: 
            [
                new OpenLayers.Control.Navigation(),
                new OpenLayers.Control.PanZoomBar(),
                new OpenLayers.Control.Attribution()
            ]
        }
    );

    var mapnik = new OpenLayers.Layer.OSM();
    mapnik.transitionEffect = 'resize';
    osmap.addLayer(mapnik);

    var vectors = new OpenLayers.Layer.Vector("Overlay");
    osmap.addLayer(vectors);

    var wgs84Proj = new OpenLayers.Projection("EPSG:4326"); // WGS 1984 Projection
    var osmapProj = osmap.getProjectionObject(); // this will be Spherical Mercator Projection for OSM

    // Loop through the table rows...
    for (var row=1; row < elmnts.length; row++) 
    {
        var AVal = elmnts[row].cells[ACol].innerHTML;
        var BVal = elmnts[row].cells[BCol].innerHTML;
        var CVal = elmnts[row].cells[CCol].innerHTML;           
        var lonVal = Number(elmnts[row].cells[LonCol].innerHTML);
        var latVal = Number(elmnts[row].cells[LatCol].innerHTML);

        if (lonVal != 0 && latVal != 0) 
        {
            // Adjust bounding coordinates
            if (lonVal < minX) minX = lonVal;
            if (lonVal > maxX) maxX = lonVal;
            if (latVal < minY) minY = latVal;
            if (latVal > maxY) maxY = latVal;

            vectors.addFeatures(
                new OpenLayers.Feature.Vector(
                    new OpenLayers.Geometry.Point(latVal,lonVal),
                    {description:'This is the value of<br>the description attribute'},
                    {externalGraphic: 'http://wiki.openstreetmap.org/wiki/File:Ol_icon_blue_example.png', graphicHeight: 25, graphicWidth: 25, graphicXOffset: 0, graphicYOffset: 0}
                )
            )
        }
    }

    var bounds = new OpenLayers.Bounds(minX,minY,maxX,maxY).transform(wgs84Proj,osmapProj);
    osmap.zoomToExtent(bounds, false);
}   

window.onload = initialise;

<div id="data">
<table>
    <tr>
        <td>A</td>
        <td>B</td>
        <td>C</td>
        <td>LON</td>
        <td>LAT</td>
    </tr>
    <tr>
        <td>1</td>
        <td>11</td>
        <td>111</td>
        <td>28.00</td>
        <td>-26.00</td>
    </tr>
    <tr>
        <td>2</td>
        <td>22</td>
        <td>222</td>
        <td>28.00</td>
        <td>-26.20</td>
    </tr>
    <tr>
        <td>3</td>
        <td>33</td>
        <td>333</td>
    <td>28.50</td>
    <td>-26.50</td>
</tr>
<tr>
    <td>4</td>
    <td>44</td>
    <td>444</td>
    <td>27.00</td>
    <td>-25.00</td>
</tr>


Solution

  • EDITED : fixed

    the markers are not being rendered as the url for the external graphic is incorrect. for some reason openlayers is not reporting error simply adding the features to the unrenderedfeatures variable.

    by changing the url to http://wiki.openstreetmap.org/w/images/e/e7/Ol_icon_blue_example.png the features render, although they are in the atlantic?

    EDITED: to include point transformation from wgs84 to spherical

    If the data you need for the markers is in a javascript array you could do something similar to the below in a loop.

    var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
    
    // Define markers as "features" of the vector layer:
    var feature = new OpenLayers.Feature.Vector(
            new OpenLayers.Geometry.Point( -0.1279688, 51.5077286).transform(wgs84Proj,osmapProj),
            {description:'This is the value of<br>the description attribute'} ,
            {externalGraphic: 'http://wiki.openstreetmap.org/w/images/e/e7/Ol_icon_blue_example.png', graphicHeight: 25, graphicWidth: 21, graphicXOffset:-12, graphicYOffset:-25  }
        );    
    vectorLayer.addFeatures(feature);
    

    you would abviously need to loop through your array and get the needed data and add it to the feature when you create it.

    Is this the sort of thing you were after?