0

I am implementing a geolocation/position tracking functionality with openlayers5 and angular 6. Even though I dont get any errors and this seems to work fine, I dont get the coords right away. Here is my geolocation-related code.

ngOnInit() {
//initialize everything in the ngOnInit
    //set it
    this.geolocation = new Geolocation({      
      trackingOptions: {
        enableHighAccuracy: true
      },
      projection: 'EPSG:3857'
    });

    //handle errors
    this.geolocation.on('error', (error) => {
      this.geolocationerror=true;
      this.geolocationmsg = error;
    });

    //accuracy
    this.accuracyFeature = new Feature(); 
    this.geolocation.on('change:accuracyGeometry', ()=> {
      this.accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
    });

    //position point
    this.positionFeature = new Feature();
    this.positionFeature.setStyle(new Style({
      image: new CircleStyle({
        radius: 6,
        fill: new Fill({
          color: '#3399CC'
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 2
        })
      })
    }));

    //track position
    this.geolocation.on('change:position', ()=> {
      let coordinates = this.geolocation.getPosition();
      this.positionFeature.setGeometry(coordinates ?
        new Point(coordinates) : null);
    });

    //on smaller screens toggle the geolocation on automatically
    if(window.innerWidth < 600){
      this.isChecked = true;
    }    

    //geolocation has its own vector layer
    this.geolocsource = new VectorSource({});
    this.geoloclayer = new VectorLayer({
      source: this.geolocsource,
      title:'location'
    });

  }//ngOnInit closes here


  //toggle geolocation on/off
  toggleGeolocation(checked){
    //erase any previous errors    
    this.geolocationmsg='';
    this.geolocationerror=false;
    ////toggled on
    if(checked){
      this.geolocation.setTracking(checked); //set on
      this.geolocsource.addFeatures([this.accuracyFeature, this.positionFeature]) ;
      this.geolocOn = true; // to show info in html     
      let center = this.geolocation.getPosition();
      //zoom there
      if (center){
        this.olmap.getView().animate({
          center: center,
          duration: 2000,
          zoom:16
        });        
      }
      //show the geolocation coords in html all the time
      this.geolocLiveCoords = this.geolocation.getPosition();
    }
    else{ //geolocation off
      this.geolocation.setTracking(checked);      
      this.geolocOn = false;
      this.geolocsource.clear();
      this.geolocLiveCoords='';
    }    
  }

and this is the HTML part

<label for="track">track position<input id="trackpos" type="checkbox" [(ngModel)]="isChecked" (change)="toggleGeolocation(isChecked)"/></label>
<div  *ngIf='geolocationerror'>{{geolocationmsg}}</div>
<div  *ngIf='geolocOn'>{{geolocLiveCoords}}</div>

The checkbox is automatically checked for smaller screens.

In any case, even though I get no errors, I have to manually check-unckeck the checkbox myself a couple of times in order to see the geolocation coords and for the whole code to work. It does not work the first time I turn it on, it gets no coords, so I turn it off and on again. After that it works fine, as it should.

What is the problem here? How can I fix it? Please advice.

Thanks

codebot
  • 517
  • 8
  • 29
  • 55

1 Answers1

1

You're only turning on the tracking when you call toggleGeolocation with true which, at this stage, only happens then you check the check-box. If you want it to start straight away, you should call it at the end of your ngOnInit method:

this.toggleGeolocation(this.isChecked);
Simon K
  • 2,762
  • 1
  • 11
  • 20
  • That is a good idea, but even then, I have to manually check-unckeck the checkbox myself a couple of times in order to see the geolocation coords and for the whole code to work. That is the problem : In any case, I have to toggle a couple of times manually in order for geolocation to work. As if it doesn't work right away or it doesnt have coords the first time it is turned on. Thanks – codebot Aug 06 '18 at 11:21
  • Hi again. I know what causes the error. Geolocation takes some time to get the position, as it normally does. In that little time, the `if(center)this.olmap.getView().animate({` part of the `toggleGeolocation` function is false, does not enter the code block and it never zooms to that point. There is a point after a little while, but because of that `if`, the map never zooms there. Now, I dont know how to fix this, because none of `addFeatures` or `getPosition` have a callback that I can safely use. Any other idea on when to zoom after the geolocation actually has a point? Thanks – codebot Aug 06 '18 at 14:52
  • 1
    I had a dig through their documentation and couldn't find any way of getting a callback from it. Have you tried seeing if, after making the call to `getPosition`, the generic `geolocation.on('change', (event) => { ... })` gets fired? Or maybe you have to wait until the first time it gets fired before you can use `getPosition`? If they're not using that event then the only thing I can see working is using an interval timer to check and wait for a result. – Simon K Aug 06 '18 at 22:28
  • Since this problem changed context, I started a new, more specific question. I also include a new solution that I tried(and failed). You can check it [here](https://stackoverflow.com/questions/51726230/wait-until-openlayers-5-geolocation-returned-a-value) if you like. Thank you for your time. – codebot Aug 07 '18 at 11:59