1

Using OpenLayers, I am creating a vector layer over a map. This vector layer is created from an OSM xml file.

My purpose is to do some experiments in Prolog with this data, for example, querying the shortest path (following the declared "ways" in the OSM file) that will visit certain amounts of POIs, given a starting POI.

My problem is that when I load the nodes and ways in my map basically I see a big mess of features, too close to each other and some of them irrelevant.

My first idea was to filter some of these nodes in the original OSM xml file using XSLT, but after doing this filtering the map did not render the vector layer at all anymore. After some experimentation I realized that the problem was that the "way" elements were referencing non-existing node elements (since I filtered them using XSLT).

I could also have deleted the "ways" elements that reference non existing nodes (using XSLT again), but this does not seem to be a good idea since then I would be loosing valuable information for calculating the shortest path and other graph typical problems.

Then I arrived to the conclusion that I do not want to delete certain nodes, but just trying to make some of them non-visible by default in the map.

Then I use XSLT again to change the "visible" attribute to certain nodes. But the problem is that all the nodes in the file are shown in the map anyway, even if they have the attribute "visible" set to false, as in this example:

<osm version="0.6" generator="CGImap 0.0.2">
  <bounds minlat="50.8319000" minlon="4.3355000" maxlat="50.8599000" maxlon="4.3708000"/>
  <node id="125892" lat="50.8500083" lon="4.3553223" user="eMerzh" uid="15399" visible="false" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
...
</osm>

Below the code I am using to create the vector layer from the OSM file:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>My OpenLayers Map</title>
  <script src="http://maps.google.com/maps/api/js?sensor=false"></script>
  <script type='text/javascript' src='OpenLayers.js'></script>
  <script type='text/javascript'>
    var map;
    var lat=50.8467493;
    var lon=4.3524950;
    var zoom=11;

    function init() {
        map = new OpenLayers.Map('map_element', {
            maxResolution: 156543.0399,
            numZoomLevels: 16,
            units: 'm',
            projection: new OpenLayers.Projection("EPSG:900913"),
            displayProjection: new OpenLayers.Projection("EPSG:4326")});

        var osm_layer = new OpenLayers.Layer.OSM(
            'OpenStreetMap Layer'
        );

        //Initialise the vector layer using OpenLayers.Format.OSM
        var pois_layer = new OpenLayers.Layer.Vector("Brussels POIs", {
            strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({
                url: "brussels_center_filtered.osm",   
                format: new OpenLayers.Format.OSM()
                }),
                projection: new OpenLayers.Projection("EPSG:4326")
            });

        map.addLayers([osm_layer, pois_layer]);
        map.addControls([new OpenLayers.Control.LayerSwitcher({})]);

        var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
        map.setCenter (lonLat, zoom);
    }

  </script>
</head>

<body onload='init();'>
    <div id='map_element' style='width: 500px; height: 500px;'></div>
</body>
</html>

1 Answer 1

3

OpenLayers OSM protocol does not know about 'visible' nodea, but you could easily extend the base class methods with a little bit of code that checks for the visibile attribute before adding the node to the list of nodes like the following (I hope your javascript-fu is strong, alsoe beware that this is untested code so it could not run right the first time):

    //Initialise the vector layer using OpenLayers.Format.OSM
    var pois_layer = new OpenLayers.Layer.Vector("Brussels POIs", {
        strategies: [new OpenLayers.Strategy.Fixed()],
        protocol: new OpenLayers.Protocol.HTTP({
            url: "brussels_center_filtered.osm",   
            format: new OpenLayers.Format.OSM({
                getNodes: function(doc) {
                        var node_list = doc.getElementsByTagName("node");
                        var nodes = {};
                        for (var i = 0; i < node_list.length; i++) {
                            var node = node_list[i];
                            if(node.getAttribute("visible")) {
                                var id = node.getAttribute("id");
                                nodes[id] = {
                                    'lat': node.getAttribute("lat"),
                                    'lon': node.getAttribute("lon"),
                                    'node': node
                                };
                            }
                        }
                        return nodes;
                    },
            })
            }),
            projection: new OpenLayers.Projection("EPSG:4326")
        });
3
  • thanks for your answer @unicoletti. The problem I see is that with this strategy the non-visible nodes will not be present at all. As far as I understand that create problems if I have "way" elements that reference them (but tell me please if that is not the case), so I cannot just drop them from the vector layer, but I should change their visibility only. Is there a way to do that ?. What I am trying to avoid is having a big mess of points representing nodes in my map, I do need all of them (for drawing the ways) but I do not want to see all the dots, but only certain of them.
    – Sergio
    May 24, 2012 at 10:49
  • I'm afraid what you want to do is a bit difficult w/o looking at the actual data and even then it might require some work. Please update you question so that it is more clear what you are trying to achieve.
    – unicoletti
    May 24, 2012 at 11:35
  • hi @unicoletti, I have just added more details to my question, thanks for any feedback!
    – Sergio
    May 24, 2012 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.