I'm making a map with OpenLayers that pulls data from a database and parses that data through an API to display it onto the map, and that section is working completely fine (see: https://i.stack.imgur.com/AHMZn.png) however, when trying to make the icons clickable I'm running into issues. I'm not sure if I have to do something different when accounting for multiple icons, but I've tried to follow the documentation at https://openlayers.org/en/latest/examples/icon.html to no help. I'm essentially trying to display the MMSI (ID of the vessels) above the ships as a pop-up when the ship is clicked on, but it isn't really working properly. It'll mouse over the icons properly, but clicking doesn't really do anything. If anyone can help, it's greatly appreciated. I've attached my index.js below:
const { Client } = require('pg')
import "ol/ol.css";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import Map from "ol/Map";
import View from "ol/View";
import Overlay from 'ol/Overlay';
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { defaults as defaultControls, FullScreen } from "ol/control";
import OSM from "ol/source/OSM";
import { fromLonLat } from "ol/proj";
import VectorSource from "ol/source/Vector";
import { Icon, Style } from "ol/style";
const newportLonLat = [-71.307607, 41.529193];
const newportWebMercator = fromLonLat(newportLonLat);
//const text = 'SELECT DISTINCT mmsi, MAX(basedatetime), lat, lon FROM public.vessels GROUP BY mmsi, lat, lon ORDER by MAX(basedatetime) DESC, mmsi, lat, lon'
function loadJSON() {
var data_file = "http://localhost:3000/latlong";
var http_request = new XMLHttpRequest();
try{
// Opera 8.0+, Firefox, Chrome, Safari
http_request = new XMLHttpRequest();
}catch (e) {
// Internet Explorer Browsers
try{
http_request = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try{
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e) {
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
http_request.onreadystatechange = function() {
if (http_request.readyState == 4 ) {
// Javascript function JSON.parse to parse JSON data
console.log(http_request);
var jsonObj = JSON.parse(http_request.responseText);
var allIcons = [];
for(var i = 0; i < jsonObj.length - 1; i++){
console.log("-----------")
console.log("Latitude: ", jsonObj[i]['lat'])
console.log("Longitude: ", jsonObj[i]['lon'])
console.log("ID: ", jsonObj[i]['mmsi'])
var lat = jsonObj[i]['lat']
var long = jsonObj[i]['lon']
var mmsi = jsonObj[i]['mmsi']
var iconFeature = new Feature({
geometry: new Point(fromLonLat([long, lat])),
name: mmsi,
population: 4000,
rainfall: 500
});
var iconStyle = new Style({
image: new Icon(
/** @type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: "fraction",
anchorYUnits: "pixels",
src: "https://i.imgur.com/P30vpnp.png",
scale: 0.5
})
)
});
iconFeature.setStyle(iconStyle);
allIcons.push(iconFeature);
}
var map = new Map({
controls: defaultControls().extend([new FullScreen()]),
layers: [
new TileLayer({
source: new OSM()
}),
new VectorLayer({
style: function(feature) {
return feature.get("style");
},
source: new VectorSource({ features: allIcons })
})
],
target: document.getElementById('map'),
view: new View({
center: newportWebMercator,
zoom: 3
})
});
var element = document.getElementById('popup');
var popup = new Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -50]
});
map.addOverlay(popup);
// display popup on click
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature) {
return feature;
});
if (feature) {
var coordinates = feature.getGeometry().getCoordinates();
popup.setPosition(coordinates);
$(element).popover({
placement: 'top',
html: true,
content: feature.get('name')
});
$(element).popover('show');
} 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' : '';
});
}
}
http_request.open("GET", data_file, true);
http_request.send();
}
loadJSON();