USSR
USSR

Reputation: 321

Applying custom icons based on fetched data in Openlayers 3

We trying to upgrade our maps in our app, and here is a lot of differences between OL2 and OL3. We would like to apply different icons (images) to our map, based on the data, e.g. if Project status is opened - then use this icon, if Project status is closed- then use another one etc. So far, we were able to apply one kind of icon to the all Projects. But cannot figure out how to use multiple ones. I've created the multiple styles and applied to the features, however it works well with the random numbers, but when I try use the same code with our data from DB (array format) it looks like it is applying first style to the whole bulk of projects.

Here is my JS code:

    (function(){
    var vectorSource = new ol.source.Vector({
      //create empty vector
    });

    (function(){
    var vectorSource2 = new ol.source.Vector({
      //create another empty vector
    });

    //create a bunch of icons and add to source vector
    for (var i=0;i<10;i++){

    var budget = 'Budget:£133,876.99';
    var proj_manager = 'Craig Morgan';
    var href = '<a href="http://www.bbc.co.uk">View Project</a>';

        var iconFeature = new ol.Feature({
        geometry: new  
            ol.geom.Point(ol.proj.transform([Math.random()*360-180, Math.random()*180-90], 'EPSG:4326',   'EPSG:3857')),
        name: 'Project' + i +'<br>'+href +'<br>'+ proj_manager +'<br>' + budget,
        icon_a: 'map-icon-small.png '
        });

        vectorSource.addFeature(iconFeature);           
    }       


    for (var i=0;i<15;i++){

    var budget = 'Money:£100,555.11';
    var proj_manager = 'Bob Johnson';
    var href = '<a href="http://www.cnn.com">View Project</a>';

        var iconFeature2 = new ol.Feature({
        geometry: new  
            ol.geom.Point(ol.proj.transform([Math.random()*360-180, Math.random()*180-90], 'EPSG:4326',   'EPSG:3857')),
        name: 'Project' + i +'<br>'+href +'<br>'+ proj_manager +'<br>' + budget,
        icon_b: 'googleMapPointer.png '
        });

        vectorSource2.addFeature(iconFeature2); 
    }       


    //create the style
    var iconStyle = new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
        anchor: [0.5, 0.5],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        opacity: 0.75,
        src: "http://obermain.com/assets/images/general/"+ iconFeature.get('icon_a')
      }))
    });


    /************** adding another style **********************/

    var iconStyle2 = new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
        anchor: [0.5, 0.5],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        opacity: 1,
        src: "http://www.stsoman.com/images/"+ iconFeature2.get('icon_b')
      }))
    });



    //add the feature vector to the layer vector, and apply a style to whole layer
    var vectorLayer = new ol.layer.Vector({
      source: vectorSource,
      style: iconStyle
    });

   var vectorLayer2 = new ol.layer.Vector({
      source: vectorSource2,
      style: iconStyle2
    });

/************ set up the map *********************/


var map = new ol.Map({
    layers: [
    new ol.layer.Tile({
        source: new ol.source.OSM()}),
        vectorLayer, vectorLayer2],
        target: document.getElementById("map"),
        view: new ol.View({
        center:  [0, 0],
        zoom: 4
    })
});             


/********************* getting popup element by id *********************************/   

var element = document.getElementById('popup');

var popup = new ol.Overlay({
    element: element,
    autoPan: true,
    positioning: 'center-center',
    stopEvent: false
});

map.addOverlay(popup);



// display popup on click

map.on('click', function (evt) {
    var feature = map.forEachFeatureAtPixel(evt.pixel,

    function (feature, layer) {
        return feature;
    });
    if (feature) {
        var geometry = feature.getGeometry();
        var coord = geometry.getCoordinates();
        popup.setPosition(coord);
        $(element).popover({
            'placement': 'auto top',
                'html': true,
                'content': feature.get('name')
        });
        $(element).popover('show');

        //FIX THAT MESSES UP THE POSITION OF THE POPOVER        
        $('.popover-content').html( '<pre>' + feature.get('name') + '</pre>' );

    } else {
        $(element).popover('destroy');
    }
});

// change mouse cursor when over marker
map.on('pointermove', function (e) {
    if (e.dragging) {
        $(element).popover('destroy');
        return;
    }
    var pixel = map.getEventPixel(e.originalEvent);
    var hit = map.hasFeatureAtPixel(pixel);
    map.getTarget().style.cursor = hit ? 'pointer' : '';
});

        })();
})();

And here is HTML:

    <script src="ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script src="http://openlayers.org/en/v3.10.1/build/ol.js"></script>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script>

<div id="map"></div>
<div id="popup"></div>

So this code above works perfectly well, however, when I do create a PL/SQL package and fetching the data from db, first style applied to all projects. How I can specify to which project apply exact style (icon). The data fetched from db is in array format, and if I manually insert it into the code it works well too. Any help? Thanks

Upvotes: 1

Views: 741

Answers (1)

Jonatas Walker
Jonatas Walker

Reputation: 14150

You didn't show how do you store and how do you read from db. But a solution can be: store an identifier on each feature so when you read you will based on it.

Maybe:

new ol.Feature({
  geometry: new ol.geom.Point(),
  project: project_identifier // <---- you are saving these properties on db, right?
});

Supposing you get an array from db:

array_features.forEach(function(feature){
  // whose project are you
  var project = feature.get('project');
  // decide what you do
});

Upvotes: 1

Related Questions