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

Hi Jack,

Could you give our SDK 6.0 a try? We changed some underlying location mechanics in the last release.


Best regards,

Andreas

Andreas,

I saw your SDK 6.0 trailer and it's really cool, but our purchase doesn't include SDK 6. Is there anything I can do with SDK 5?

Thanks.

Hi Jack,

It highly depends on what it is exactly that you want to do. The new features we introduced with SDK 6 included Instant Tracking and Gestures whereas there were many improvements as well. If you need to use our new features, as included in our video as well, then you would need an SDK 6 license. So depending on what you want to do you have your answer. If you have any sales/purchase/update licenses questions then please write an email at sales@wikitude.com

 

Thanks

Eva

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.

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

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,

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

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,

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

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,

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


Best regards,

Andreas

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? )

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.

Login or Signup to post a comment