Open pascal101 opened 4 years ago
Based on the code you have given, you aren't setting popupContent.gpsLongitude
and popupContent.gpsLatitude
so the overlay will not be positioned hence you won't see the popup.
Regarding mouseover, you can do it by handling the map pointermove
event and calling map.forEachFeatureAtPixel(..)
once to get the feature.
Thank you very much for your answer.
I made some changes in my code like you can see below. Now a popup appears on click event on a DEVICE. But it is always at the bottom left of the screen, and quite far from the clicked point, as you can see on the image below.
I don't understand why.
First, I updated my Angular framework to the 10 version and librairies. I also updated librairies like ol, bootstrap, ngx-openlayers In my package.json :
"dependencies": {
"@angular/animations": "^10.1.2",
"@angular/common": "^10.1.2",
"@angular/compiler": "^10.1.2",
"@angular/core": "^10.1.2",
"@angular/forms": "^10.1.2",
"@angular/localize": "^10.1.2",
"@angular/platform-browser": "^10.1.2",
"@angular/platform-browser-dynamic": "^10.1.2",
"@angular/platform-server": "^10.1.2",
"@angular/router": "^10.1.2",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@popperjs/core": "^2.5.1",
"angular-font-awesome": "^3.1.2",
"bootstrap": "^4.5.2",
"core-js": "^3.6.5",
"ngx-bootstrap": "^6.1.0",
"ngx-openlayers": "^0.8.22",
"ol": "^6.4.3",
"popper.js": "^1.16.1",
"rxjs": "^6.6.3",
},
Here is my new template code :
<aol-map [logo]="true" [width]="width" [height]="height" (onClick)="onClick($event)">
<aol-interaction-default></aol-interaction-default>
<aol-view [zoom]="zoom">
<aol-coordinate [x]="longitude" [y]="latitude" [srid]="'EPSG:4326'"></aol-coordinate>
</aol-view>
<aol-layer-tile [opacity]="opacity">
<aol-source-osm></aol-source-osm>
</aol-layer-tile>
<aol-layer-vector [opacity]="opacity">
<aol-source-vector>
<aol-feature *ngFor="let device of devices" (click)="setPopupContent(device) [id]="device.deviceId">
<aol-geometry-point>
<aol-coordinate [x]="device.gpsLongitude" [y]="device.gpsLatitude" [srid]="'EPSG:4326'">
</aol-coordinate>
</aol-geometry-point>
<aol-style>
<aol-style-circle [radius]="10">
<aol-style-stroke [color]="'black'" [width]="width" ></aol-style-stroke>
<aol-style-fill [color]="'green'"></aol-style-fill>
</aol-style-circle>
</aol-style>
</aol-feature>
<aol-overlay *ngIf="popupContent.shown">
<aol-coordinate [x]="popupContent.feature.gpsLongitude" [y]="popupContent.feature.gpsLatitude" [srid]="'EPSG:4326'">
</aol-coordinate>
<aol-content>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content">DEVICE : gpsLongitude {{ popupContent.feature.gpsLongitude }} / gpsLatitude {{ popupContent.feature.gpsLatitude }}</div>
</div>
</aol-content>
</aol-overlay>
</aol-source-vector>
</aol-layer-vector>
Here is the new typescript code :
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core'
import { GeoLocationService } from 'src/app/common/services/geo-location.service'
import { marker } from './marker.image'
import * as olProj from 'ol/proj'
import { HttpClient } from '@angular/common/http'
import { Subscription } from 'rxjs'
import { Device } from '../../common/model/device'
import { ReportManagementService } from 'src/app/common/services/report-management.service'
import { MapBrowserEvent, Feature } from 'ol';
import { Map } from 'ol/Map';
import { View } from 'ol/View';
import { TileLayer } from 'ol/layer/Tile';
import { XYZ } from 'ol/source/XYZ';
import { NgbdTooltipBasicModule } from 'src/app/shared/tooltip/tooltip.module'
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { Overlay, OverlayPositioning} from 'ol/Overlay';
import { toLonLat } from 'ol/proj';
import { toStringHDMS } from 'ol/coordinate';
@Component({
selector: 'app-osm-view',
templateUrl: './osm-view.component.html',
styleUrls: ['./osm-view.component.css'],
providers: [HttpClient, GeoLocationService]
})
export class OsmViewComponent implements OnInit {
public features: Device[];
public popupContent: { shown: boolean; feature: Device};
constructor(private httpClient: HttpClient,
private geoLocationService: GeoLocationService,
private reportManagementService: ReportManagementService
) {
this.features = [];
this.popupContent = {
shown: false,
feature: undefined
};
}
public onClick(event: MapBrowserEvent) {
event.map.forEachFeatureAtPixel(event.pixel, (feature: Feature) => {
console.log("onClick : event.pixel : ", event.pixel);
console.log("onClick : event : ", event);
let featureId: number;
featureId = feature.getId();
console.log("onClick : feature : ", feature);
console.log("onClick : feature.getId() : ", feature.getId());
let device = this.devices.find(x => x.deviceId === featureId);
console.log("onClick : device : ", device);
this.setPopupContent(device);
});
}
public setPopupContent(feature: Device) {
this.popupContent.shown = true;
this.popupContent.feature = feature;
console.log("In setPopupContent method : this.popupContent.shown : ", this.popupContent.shown);
console.log("In setPopupContent method : this.popupContent.feature : ", this.popupContent.feature);
}
You can see in the browser console the result of my console.log trace
onClick : event.pixel : Array [ 628, 844.4000244140625 ]
onClick : event : Object { type: "click", target: {…}, map: {…}, frameState: {…}, originalEvent: pointerdown, pixel: (2) […], coordinate: (2) […], dragging: false, b: {…} }
onClick : feature : Object { Ua: {}, sa: {}, ra: {…}, f: 5, cp: 30, O: {…}, c: 57, a: "geometry", g: {…}, j: b(), … }
onClick : feature.getId() : 57
onClick : device : Object { deviceId: 57, gpsLatitude: 45.71499557422359, gpsLongitude: 4.806758317260741, reports: [], trackingSystem: null, sensorCharacteristic: (1) […], sensorType: (1) […], active: true, visible: false }
In setPopupContent method : this.popupContent.shown : true
In setPopupContent method : this.popupContent.feature : Object { deviceId: 57, gpsLatitude: 45.71499557422359, gpsLongitude: 4.806758317260741, reports: [], trackingSystem: null, sensorCharacteristic: (1) […], sensorType: (1) […], active: true, visible: false }
Here is the styles I got from https://openlayers.org/en/latest/examples/popup.html
<style>
.map {
width: 100%;
height:400px;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>
1) So the popup is displayed but outside the map. What is the problem, how to correct that ?
2) As you advised me regarding mouseover, i tried the map pointermove event ( (mouseover)="mouseover($event)" ) and I had "TypeError: event.map is undefined" once my mouse is on the map.
3) I tried a little test with mouseover event but OUTSIDE the map and it works perfectly :
<p (mouseover)="mouseover()" placement="top" tooltip="Tooltip on top"><b>Mouseover</b> here</p>
<h1>{{counter}} </h1>
Please help. Thank you in advance...
pointermove
event rather than mouseover
:
<aol-map (pointermove)="pointerMoved()">
Is there a way to capture mouse over event on a aol-feature on a OSM map ? I have a device list (points) which are dysplayed on the map and my goal is to be able to show a pop-up once the mouse is over a device (aol-feature). I'm beginner on OpenLayer librairie and on OSM map.
First I tried to follow this explaination with onClick event : https://github.com/quentin-ol/ngx-openlayers/issues/84 But it does not work for me.
I'm using Angular 7 with : bootstrap: 4.1.3, ngx-bootstrap: 5.6.1, ngx-openlayers : 0.8.22, ol: 6.4.3.
Here is my template code :
Here is the typescript code :
You can see in the browser console the result of my console.log trace
So when I click on a device, the event is captured by no popup is displayed. What is the problem ?
How to modify the code if I would like to do this on mouse over event ? I tried this (mouseover)="mouseover($event)" but it does not work.
Please help. Thank you in advance...