I have this code with openstreetmaps (is a circle, then I have more markers named marker1, marker2, marker3 and so on), but property curosor: pointer doesn't work (I tried with a lot of browsers).
Also tried with css:
.ol-marker .ol-icon {
cursor: pointer;
}
The same, doesn't work.
// Create a marker feature 1
var marker1 = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([14.3619382, 46.0649361])),
name: 'some text',
description: 'other some text'
});
// Create a marker style 1
var markerStyle1 = new ol.style.Style({
image: new ol.style.Icon({
src: '/assets/images/ico.png',
scale: 1 }),
cursor: 'pointer'
});
// Set style to marker feature 1
marker1.setStyle(markerStyle1);
// Add the marker feature 1 to the vector source
vectorSource.addFeature(marker1);
#mkrieger1 sure, it was typing error in description, but if you see the code it's correct
doesn't work means that cursor also on marker is standard type, not pointer. No error in console, I'm using this version cdn.jsdelivr.net/npm/ol#v7.2.2/dist/ol.js
Related
I want to create on click event on the marker which zooms at a specific level upon click. current code loads marker and upon click zooms to the maximum zoom level of marker. I want to add a specific zoom level in code so when click event happens on the marker it should set view at that zoom level .i have raster tiles on the map at zoom level 16 and above so, when I click on the marker it should zoom to raster tiles and hide marker from there.
var marker = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: "data.js"
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
scale:0.03,
src: "img.png"
})
})
});
map.addLayer(marker);
map.on("singleclick", (event) => {
const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => {
return feature;
});
if (feature instanceof ol.Feature) {
map.getView().fit(feature.getGeometry());
}
});
Instead of using fit set the view's center and zoom
map.getView().setCenter(ol.extent.getCenter(feature.getGeometry().getExtent()));
map.getView().setZoom(16);
You can "hide" a feature by giving it a null style
feature.setStyle(null);
I'm looking for a way to render a hover feature vector only over that feature, to essentially render the hover vector over its feature without rendering over other features (specifically, LineString hovers not rendering over proximate markers)
I have hovering set up without issue as per the vector example, the features all rendering in the order I would like (LineStrings are below markers). The issue is that when a LineString is hovered over its hover feature is rendered not only over that LineString but also any marker that the LineString crosses under, and so there is a big streak of the LineString's hover over that marker. I can see how this makes sense just considering how the feature-overlaying vector works, but I can't see how to adjust it as I would like.
I've found several posts that seem to offer incongruous advice on setting a zIndex in the styles or using a renderOrder function, though none have seemed exactly applicable to this situation, or are beyond my n00b capacities. I have tried setting a zIndex on all concerned Styles as well as something along the lines of this renderOrder function, but not to the desired effect. Specifically with the latter, I couldn't figure out where to put the function so that the hover might render according to it.
Any advice is greatly appreciated!
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([132.4903, 34.0024]),
zoom: 4
})
});
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: '../static/gpx/summer3.kml',
format: new ol.format.KML({
extractStyles: false
})
}),
style: function(feature) {
return routeStyle;
},
});
vectorLayer.getSource().on('addfeature', function(event) {
event.feature.set('hoverstyle', 'route');
});
map.addLayer(vectorLayer);
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: '../static/gpx/testmoo3.kml',
format: new ol.format.KML({
extractStyles: false,
}),
}),
style: function(feature) {
return iconStyle;
},
});
vectorLayer.getSource().on('addfeature', function(event) {
event.feature.set('hoverstyle', 'route');
});
map.addLayer(vectorLayer);
var hoverStyles = {
'moo': new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/mooinb.png',
}),
'route': new ol.style.Stroke({
color: 'rgba(236, 26, 201, 0.5)',
width: 5
})
};
var routeStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(209,14,14,.6)',
width: 4
})
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/moo7.png',
}),
});
var hoverStyleCache = {}
function hoverStyler(feature, resolution) {
var hover = feature.get('hoverstyle');
var geometry = feature.getGeometry().getType();
console.log(hover);
while (geometry === 'Point') {
if (!hoverStyleCache[hover]) {
hoverStyleCache[hover] = new ol.style.Style({
image: hoverStyles[hover],
})
}
return [hoverStyleCache[hover]];
}
while (geometry === 'LineString') {
if (!hoverStyleCache[hover]) {
hoverStyleCache[hover] = new ol.style.Style({
stroke: hoverStyles[hover]
})
}
return [hoverStyleCache[hover]];
}
}
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: hoverStyler
});
var highlight;
var hover = function(pixel) {
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
if (feature !== highlight) {
if (highlight) {
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}
};
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
hover(pixel);
});
***** EDIT 1 *****
Here is a plunkr that at least illustrates what I mean (with the hover vector overlapping the marker).
I continued fiddling around and did get manage to achieve what I wanted, by separating the point and linestring 'featureOverlay' vector into two separate vectors, though to get that to work I also then had to duplicate everything that it implies (the hoverStyler function, the hover feature, etc).
As well, when I referred above to incongruous advice that came especially to the fore as I was able to set the zIndex on that any vector layer, but not in the Styles as I read in just about every other question I found but to the vector itself. Thus,
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: hoverStyler,
zIndex: 1,
});
worked (with zIndex similarly applied to ever other vector layer), but because points and linestrings share the feature Overlay that also meant that the marker's hover vector image was below the marker it was meant to hover over: applied in this way both linestring and markers or neither hover above.
I thus tried to come up with a function similar to the hoverStyler that differentiates them:
function zIndexer(feature, resolution) {
var geometry = feature.getGeometry().getType();
if (geometry === 'Point') {
return 5
}
if (geometry === 'LineString') {
return 1
}
}
but to no avail (I was unsure what exactly should be returned and tried various inputs; this as others did not work).
So I could settle for duplicated featureOverlay apparatuses, but a handy zIndex function would be of course be preferable :)
(*note: I could not get the zIndex to work in the plunkr as described above, in or out of Styles, hence it does not illustrate my later fiddling but only the original question)
***** EDIT 2 *****
I noted in a comment below on the provided answer that, while the answer works wonderfully, it did make cluster styles styled by function (not mentioned in the original post0 not work. I overcame this with the following vector, which worked but that I am not qualified to say worked well:
var clusterCache = {}
var CLM = new ol.layer.Vector({
source: new ol.source.Vector(),
style: function(feature) {
var size = feature.get('features').length;
var style = clusterCache[size]
if (size === 1) {
return [hoverStyles['moo']]
}
else if (size > 1) {
if (!style) {
style = new ol.style.Style({
image:new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/moo3Hover.png',
}),
text: new ol.style.Text({
text: size.toString(),
font: '12px Calibri,sans-serif',
fill: new ol.style.Fill({
color: '#fff'
}),
stroke: new ol.style.Stroke({
color: '#000',
width: 5
}),
offsetX: 22,
offsetY: 6,
})
}),
clusterCache[size] = style;
}
return style;
}
}
});
hoverLayers['clustermoo'] = CLM;
Approach
The basic idea is you need separate hover layers for the route and the icons (top to bottom):
Icon hover layer
Icon layer
Route hover layer
Route layer
This will mean that say an unhovered icon will draw over the top of a hovered route.
ZIndex
You can't use the style zIndex as it applies only to features within a layer. That is, the layer zIndex has a higher precedence than the style zIndex. In your plunkr I couldn't get the layer zIndex to work at all, but it is implicit in the order the layers are added.
So, you need to:
create separate hover layers
setup the layers in the order I gave above
when hovering a feature, move it to the appropriate hover layer
when unhovering a feature, remove it from the appropriate hover layer
Style Cache
Another thing, your style cache implementation was rather dubious. In fact you do not need a style cache as your are using layer styles and they are only assigned/created once.
Plunkr
Here is an updated plunkr with the above changes: https://plnkr.co/edit/gpswRq3tjTTy9O0L
var createHoverLayer = function(style) {
return new ol.layer.Vector({
source: new ol.source.Vector(),
style: style,
});
}
var hoverLayers = {};
hoverLayers['route'] = createHoverLayer([hoverStyles['route']]);
hoverLayers['moo'] = createHoverLayer([hoverStyles['moo']]);
map.addLayer(routeLayer);
map.addLayer(hoverLayers['route']);
map.addLayer(mooLayer);
map.addLayer(hoverLayers['moo']);
var highlight;
var hover = function(pixel) {
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
if (feature !== highlight) {
if (highlight) {
var highlightType = highlight.get('type');
hoverLayers[highlightType].getSource().removeFeature(highlight);
}
if (feature) {
var featureType = feature.get('type');
hoverLayers[featureType].getSource().addFeature(feature);
}
highlight = feature;
}
};
Alternative Approach
do not use separate hover layers at all
use per feature styling via style function
when the feature is hovered/unhovered, set a 'hovered' property on it
to true/false
in the style function, check this property and use the appropriate
style
you will need a style cache with this method
I have a click event attached to my map. On this click event I trigger a function which is supposed to add a feature to the map, but now nothing happens. I tried it like so:
function boo (map, layer){
var source = layer.getSource();
var thing = new ol.geom.Polygon( [[
ol.proj.transform([-16,-22], 'EPSG:4326', 'EPSG:3857'),
ol.proj.transform([-44,-55], 'EPSG:4326', 'EPSG:3857'),
ol.proj.transform([-88,75], 'EPSG:4326', 'EPSG:3857')
]]);
var featurething = new ol.Feature({
name: "Thing",
geometry: thing,
style: function() {
console.log("Never see this text");
return new ol.style.Style({
fill: new ol.style.Fill({
color: "rgba(192,192,192,1)"
}),
stroke: new ol.style.Stroke({
color: "rgba(192,192,192,1)",
width: 10
})
})
}
});
source.addFeature( featurething );
// see no error messages, but still no feature is added to the map
}
It is a OL3 bug
Not so fast.
The first argument of your function should be the click event. Another error: there's no style parameter in ol.Feature constructor.
Set the feature style after its creation. So:
featurething.setStyle(some_style_or_a_function);
While ago I had help over so about setting up a project where I need to mark random building in NYC and display some info about the building, long story short, I have displayed a openstreetmap using openlayers3, view is fix to Astoria(Queens, NYC).
Now popup is working but markers are not displaying.
I have tried to experiment and change geometry from this
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.927870, 40.763633]))
to this ol.geom.Point(ol.proj.transform([-73.920935,40.780229], 'EPSG:4326', 'EPSG:3857')),
and use transform instead fromLonLat, but that didn't displayed them, next thing was src in styleIcon, I have download the standard openlayers3 marker and tried to add it from the image folder like src: 'img/icon.png', but that didn't work to.
Can someone please help me understand what is going on, why are mine markers not displaying properly on the map?
This is the JSFiddle for this project, you will see the popup working but no markers.
This JSFiddle is updated and it is working now, markers are displaying properly.
/* Create the map */
// Elements that make up the popup
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
// Add a click handler to hide the popup.
// #return {boolean}.
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
// Create an overlay to anchor the popup
// to the map
var overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
// setting up coordinates for map to display
var city = ol.proj.transform([-73.920935,40.780229], 'EPSG:4326', 'EPSG:3857');
// setting up openlayer3 view
var view = new ol.View({
center: city,
zoom: 15
});
// Create the map
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
crossOrigin: 'anonymous'
})
})
],
overlays: [overlay],
target: 'map',
view: view
});
// Setup markers
var markers = new ol.layer.Vector({
source: new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.927870, 40.763633])),
name: 'Crescent St',
description: 'Apartment'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.917356, 40.763958])),
name: 'Long Island City',
desctiption: 'Apartment'
})
]
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixel',
opacity: 0.75,
src: 'https://openlayers.org/en/v3.12.1/examples/data/icon.png',
})
})
});
map.addLayer(markers);
// Setting up click handler for the map
// to render the popup
map.on('singleclick', function(evt) {
var name = map.forEachFeatureAtPixel(evt.pixel, function(feature) {
return feature.get('name');
})
var coordinate = evt.coordinate;
content.innerHTML = name;
overlay.setPosition(coordinate);
});
map.on('pointermove', function(evt) {
map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : '';
});
just remove the https from your src style.
Instead of src: 'https://openlayers.org/en/v3.12.1/examples/data/icon.png',
putsrc: 'http://openlayers.org/en/v3.12.1/examples/data/icon.png',
You also need to zoom out a bit to see your marks
I am trying to change the color of a marker/icon with GoogleMaps API V3 based on user input. I can hard code the color or image link I want into the Javascript, but if I try to pass the color or link as a string variable from my Java program then it either does not show up or defaults to a red marker.
I've looked at all the following threads and at the google API:
Google Maps API 3 - Custom marker color for default (dot) marker
How do I change icon colour in Google Maps API V3?
Google Maps API 3 - Custom marker color for default (dot) marker
https://developers.google.com/maps/documentation/javascript/markers
All of which have either the link to the marker icon they want to use or the color HEX code already hard coded into the javascript.
My attempt, where address1 and color1 are both strings that are passed to the javascript from my Java code. color1's string, for example could be
"http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld•|4D8080":
function codeAddress(address1, color1){
var pinColor = color1;
address=address1;
document.geocoder.geocode( {'address': address1}, function(results, status) {
app.callFromJavascript(address1);
if (status == google.maps.GeocoderStatus.OK) {
document.map.setCenter(results[0].geometry.location);
document.map.setZoom(13);
var marker = new google.maps.Marker({
icon: pinColor,
position: results[0].geometry.location,
map: document.map
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
This results in the map centering on the location and showing the default red marker.
If I change the string passed to color1 to be "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png" then no marker shows up at all.
What am I missing that I can't get these to generate from passed variables? Is it simply not possible and mandatory that the location markers be hard coded?
So if you have a hex code already with you and you have an icon obj which looks like this
let carIcon = {
path: carsvg,
scale: 0.7,
strokeColor: 'white',
strokeWeight: 0.10,
fillOpacity: 1,
fillColor: '#404040',
offset: '2%',
anchor: new google.maps.Point(10, 25) // orig 10,50 back of car, 10,0 front of car, 10,25 center of car
};
and a marker object like this
let carmarker = new google.maps.Marker({
position: carLatLng,
map: map,
title: "Car",
icon: carIcon,
setMap: map
});
and say you want to change the color of the icon. To do that, simply use
carIcon.fillColor = '#008000';
carmarker.setIcon(carIcon);
This should make it to the color hex code you have. Hope it helps. Also, the icon should be SVG in this case for the color to change to take place.
this works fine for me :
var marker = new google.maps.Marker({
icon: new google.maps.MarkerImage("http://maps.google.com/mapfiles/ms/icons/yellow-dot.png"),
position: results[0].geometry.location,
map: document.map
});
they do not have to be hard coded , but you do have to use the object type of MarkerImage to pass the url to.
You can not just pass a hex color and expect the maps API to make a new marker based on the color you just picked. What is usually done is to like to an image url that already exists for each color that you plan to use. Then use the code the way I showed you.