Reputation: 321
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
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