Code Monkey home page Code Monkey logo

Comments (3)

wflemingnz-retired avatar wflemingnz-retired commented on May 27, 2024

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.

from ngx-openlayers.

pascal101 avatar pascal101 commented on May 27, 2024

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.

Popup_out_of_map

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...

from ngx-openlayers.

wflemingnz-retired avatar wflemingnz-retired commented on May 27, 2024
  1. Hard to say without running example(ie: stackblitz) and further investigation. Probably either a projection issue or an html layout issue
  2. Use the openlayers pointermove event rather than mouseover:
    <aol-map (pointermove)="pointerMoved()">

from ngx-openlayers.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.