Start a new topic

wikitude.setLocation not firing AR.context.onLocationChanged?

I'm using wikitude.setLocation to inject location provided by 3rd party positioning service.

I'm doing this:

wikitude.loadARchitectWorld(function (url) {
	window.positionService.onchange = function (position) {
		alert(position.latitude + ',' + position.longitude + ',' + position.accuracy);
		wikitude.setLocation(position.latitude, position.longitude, position.altitude, position.accurary);
	};

and this:

AR.context.onLocationChanged = function (latitude, longitude, altitude, accurary) {
	AR.context.onLocationChanged = null;
	alert(latitude + ',' + longitude + ',' + accuracy);

but it turns out that AR.context.onLocationChanged does not follow immediately after location update, and the alert shows that the value received is different from the value provided by the positioning service, so I guess the mechanism is simply not working and wikitude is using location from GPS.

Am I doing wrong?

I'm using Cordova plugin 5.1.4.


Hi Jack,

regarding the line numbers: You might be right, I had a look at the 6.0 Cordova plugin. Below is the complete if statement that handles setting of new locations. You could log the `args` parameter and check what is is included for the accuracy.


 

		/* location update */
        if ( WikitudePlugin.ACTION_SET_LOCATION.equals( action ) ) {
            if ( this.architectView != null ) {
                try {
                    final double lat = args.getDouble( 0 );
                    final double lon = args.getDouble( 1 );
                    float alt = Float.MIN_VALUE;
                    try {
                        alt = (float)args.getDouble( 2 );
                    } catch ( Exception e ) {
                        // invalid altitude -> ignore it
                    }
                    final float altitude = alt;
                    Double acc = null;
                    try {
                        acc = args.getDouble( 3 );
                    } catch ( Exception e ) {
                        // invalid accuracy -> ignore it
                    }
                    final Double accuracy = acc;
                    if ( this.cordova != null && this.cordova.getActivity() != null ) {
                        this.useCustomLocation = true;
                        cordova.getActivity().runOnUiThread(
//						this.cordova.getThreadPool().execute(
                                new Runnable() {

                                    @Override
                                    public void run() {
                                        if ( accuracy != null ) {
                                            WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, accuracy.floatValue() );
                                        } else {
                                            WikitudePlugin.this.architectView.setLocation( lat, lon, altitude );
                                        }
                                    }
                                } );
                    }

                } catch ( Exception e ) {
                    callContext.error( action + ": exception thrown, " + e != null ? e.getMessage() : "(exception is NULL)" );
                    return true;
                }
                callContext.success( action + ": updated location" );
                return true;
            } else {
				/* return error if there is no architect-view active*/
                callContext.error( action + ": architectView is not present" );
            }
            return true;
        }

 

Small demos are always good. If you find an issue, you can also send this small demo to us and we have a look at it.


Best regards,

Andreas

Andreas,

410-426 is code for ACTION_CALL_JAVASCRIPT in v5.1.4 cordova plugin code, so I guess you are mentioning the code above it, which is the lines I pasted in my last post, specifically:

 

WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, accuracy.floatValue() );
Seems it should work, however I'm always receiving 1, regardless of what I set in WikitudePlugin.setLocation. Maybe I'm making mistakes elsewhere, I'll try to repro it in a small demo.
Thanks!

Hi Jack,

You should be able so specify the accuracy in the Wikitude Cordova plugin JS API. The Android plugin tries to read it in line 410 - 426.


Best regards,

Andreas

Hi Jack,

Our last responses overlapped :) My last message was referring to the one from Feb 28, 10:40 AM.

Hi Jack,

The snippet I wanted to send you is the one you posted the last time. Sorry for the delay.


Can you help me one more time in answering the following? Is the delay between the Architect World and the Cordova application - between the Cordova application and the Wikitude Plugin - between the Wikitude Plugin and the Wikitude SDK or inside the Wikitude SDK?


Best regards,

Andreas

Andreas,

I checked my code again, and I suspect that it may be my misuse of callContext.success to do logging. I'm not familiar with cordova plugin code. I'm doing logging like this:


@Override
public void run() {
	if ( accuracy != null ) {
		callContext.success( action + ": updated location " + String.valueOf(lat) + "," + String.valueOf(lon) + "," + String.valueOf(accuracy.floatValue()));
		WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, accuracy.floatValue() );
	} else {
		callContext.success( action + ": updated location " + String.valueOf(lat) + "," + String.valueOf(lon) + "," + String.valueOf(accuracy.floatValue()));
		WikitudePlugin.this.architectView.setLocation( lat, lon, altitude );
	}
}

does it mess up the original program?

I deleted log code and I can receive location update right after I call setLocation now.

But I also find that the accuracy value in onLocationChanged is always 1 while latitude and longitude is correct. I failed to find documentation for v5.1.4 to see if it is supported in this version.

Can you confirm?

Sorry for taking your time.

Thanks.

Andreas,

As I see in WikitudePlugin.java, LocationListener ignores location change event if this.useCustomLocation is set:


 

@Override
public void onLocationChanged( final Location location ) {
	if (location!=null && !WikitudePlugin.this.useCustomLocation) {
		WikitudePlugin.this.lastKnownLocaton = location;
		if ( WikitudePlugin.this.architectView != null ) {
			if ( location.hasAltitude() ) {
				WikitudePlugin.this.architectView.setLocation( location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getAccuracy() );
			} else {
				WikitudePlugin.this.architectView.setLocation( location.getLatitude(), location.getLongitude(), location.getAccuracy() );
			}
		}
	}
}

 

and from the code in my last post, setLocation sets useCustomLocation, so once I call setLocation, it stops using default positioning.

And from my testing, there's only my injected locations, so I think it's not overwritten.

Thanks.

(BTW, you said "I send you another snippet how to stop automatic location updates on Android after a custom location was injected", where is it? )

Hi Jack,

Did you also turn off the default location injections that are started from within the Wikitude Android Cordova plugin?


Best regards,

Andreas

Andreas,

For android, I've looked into the cordova plugin code.

For setLocation, we have this:


 

if ( this.cordova != null && this.cordova.getActivity() != null ) {
	this.useCustomLocation = true;
	cordova.getActivity().runOnUiThread(
		new Runnable() {
			@Override
			public void run() {
				if ( accuracy != null ) {
					WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, accuracy.floatValue() );
				} else {
					WikitudePlugin.this.architectView.setLocation( lat, lon, altitude );
				}
			}
		} );
}

 

I added log around architectView.setLocation call, and call WikitudePlugin.setLocation every 1 second. It shows that architectView.setLocation is called with a very obvious delay. It took nearly 20 seconds for the first log to show up, with the location I injected.

Any idea?

Hi Jack,

Both code snippets I send only apply for iOS.


For Android: Can you please make sure that the injected location is really not delivered? You should get it within the Architect World but followed by other location changes. I send you another snippet how to stop automatic location updates on Android after a custom location was injected.


Best regards,

Andreas

My mistake. I actually mean we are using iOS native SDK for iOS and Cordova plugin for android. I'll take a look at the code you mentioned.

Thanks.

Hi Jack,

The snippet I send you was already for the Cordova plugin.

For your iOS implementation, simply make sure that you first inject the location using the `-injectLocationWithLatitude:longitude:altitude:accuracy:` method and then call `-setUseInjectedLocation:` afterwards.


Best regards,

Andreas

Thanks a lot, Andreas.

We're using both iOS and Cordova plugin. I've already forwarded this information to our iOS dev. And can you shed some light on the Cordova plugin also? Thanks.

Hi Jack,

On which platform are you testing? iOS, Android or both?


In case you're using iOS: The way the Wikitude Cordova plugin is implemented, the injected location will be reported as soon as another GPS update is received. To change this behaviour, simple exchange the -setLocation: method in WTWikitudePlugin.m with the implementation below. It changes the order of two internal method calls which then lead to an immediate location changed notification.


 

- (void)setLocation:(CDVInvokedUrlCommand *)command
{

    CDVPluginResult* pluginResult = nil;


    if ( self.arViewController && 4 == command.arguments.count )
    {
        float latitude = [[command.arguments objectAtIndex:0] floatValue];
        float longitude = [[command.arguments objectAtIndex:1] floatValue];
        float altitude = [[command.arguments objectAtIndex:2] floatValue];
        float accuracy = [[command.arguments objectAtIndex:3] floatValue];


        [self.arViewController.architectView injectLocationWithLatitude:latitude longitude:longitude altitude:altitude accuracy:accuracy];

        if (!self.isUsingInjectedLocation)
        {
            [self.arViewController.architectView setUseInjectedLocation:YES];
            self.isUsingInjectedLocation = YES;
        }

        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    }
    else
    {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }


    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

 


Best regards,

Andreas

Eva,

As I said in the post, I just want to inject location provided by 3rd party positioning service, but wikitude.setLocation seems not to fire AR.context.onLocationChanged. That's my question.

Thanks.

Login or Signup to post a comment