Start a new topic

How to get .wto file (object tracking ) from web service using android javascript API

Hi,

How to get .wto file (object tracking ) from web service using android javascript API?

Because on the Wikitude sample we need to import our .wto file.

All I need is my project can automatically get the new .wto file that I uploaded on my web service.


I'm using Wikitude SDK Android 8.10


Thanks


Hi Sarah,

I see that this thread covers a lot of code samples and details provided by Aitor and I'd like to add details to our support process in general to manage your expectations. For questions such as the one we're having in this thread, our approach is to give code snippets, descriptions and ideas on how to solve the problem, links to the Wikitude documentation and the SDK sample app. We're not providing 3rd party development and therefore are not implementing any code or samples. As the support is done by our core team to ensure a high quality support process, I hope you can understand that we need to work efficiently and can't provide any other details that provided by Aitor already.

Ideally, make sure that you fully understand the sample app, how it works and also seek for input in different support channels online.

Thx for your understanding,

Nicola


Hi, Aitor

I don't really understand the structure (where should I put this, where should I put that) and what should I do to show the name and the description on each object when it scanned.


This is my latest javascript code and I don't even know why and where my mistake that cause the name and the description didn't shown


 

var ServerInformation = {
    OBJECTDATA_SERVER: "https://.....",
    OBJECTDATA_SERVER_ARG_NAME: "nama_objek",
    OBJECTDATA_SERVER_ARG_DESC: "description"
};

var World = {
    loaded: false,
    objectData: [],
    drawables: [],

    init: function initFn() {
        World.requestDataFromServer();
        World.createDescriptionDrawable();
        World.createTracker();
    },

    requestDataFromServer: function requestDataFromServerFn(nama_objek, description) {

            /* Set helper var to avoid requesting places while loading. */
            World.isRequestingData = true;
            World.updateStatusMessage('Requesting places from web-service');

            /* Server-url to JSON content provider. */
            var serverUrl = ServerInformation.OBJECTDATA_SERVER + "?" + ServerInformation.OBJECTDATA_SERVER_ARG_NAME + "=" +
                nama_objek + "&" + ServerInformation.OBJECTDATA_SERVER_ARG_DESC + "=" +
                description;

            var jqxhr = $.getJSON(serverUrl, function(objectData) {
                    World.loadObjectsFromJsonData(objectData);
                })
                .error(function(err) {
                    World.updateStatusMessage("Invalid web-service response.", true);
                    World.isRequestingData = false;
                })
                .complete(function() {
                    World.isRequestingData = false;
                });
            },
    },

    loadObjectsFromJsonData: function loadObjectsFromJsonDataFn(objectData) {

            /* Loop through Object-information and create an AR.Object (=Marker) per Object. */
            for (var currentObjectNr = 0; currentObjectNr < objectData.length; currentObjectNr++) {
                var singleObject = {
                    "id": objectData[currentObjectNr].id,
                    "nama_objek": objectData[currentObjectNr].nama_objek,
                    "description": objectData[currentObjectNr].description
                };

                World.objectData.push(singleObject);
            }
    },

    createDescriptionDrawable: function createDescriptionDrawableFn() {
          titleLabel = new AR.Label(objectData.nama_objek.trunc(30), 0.7, {
                      zOrder: 1,
                      translate: {
                          x: 0.7,
                          y: 0.2
                      },

                      style: {
                          textColor: '#FFFFFF',
                          fontStyle: AR.CONST.FONT_STYLE.BOLD
                      }
              });
    },


    createTracker: function createTrackerFn() {
        this.targetCollectionResource = new AR.TargetCollectionResource("https://..../file_name.wto", {
            onError: World.onError
        });

        this.tracker = new AR.ObjectTracker(this.targetCollectionResource, {
            onError: World.onError
        });

        for (var i = 0; i < objectData.length; i++) {
                this.objectTrackable = new AR.ObjectTrackable(this.tracker, objectData[i].id, {
                    drawables: {
                        cam: World.drawables,
                    },
                    onObjectRecognized: World.objectRecognized,
                    onObjectLost: World.objectLost,
                    onError: World.onError
                });
        }
    },

    objectRecognized: function objectRecognizedFn() {
        World.hideInfoBar();
        World.setAugmentationsEnabled(true);
    },

    objectLost: function objectLostFn() {
        World.setAugmentationsEnabled(false);
    },

    setAugmentationsEnabled: function setAugmentationsEnabledFn(enabled) {
        for (var i = 0; i < World.drawables.length; i++) {
            World.drawables[i].enabled = enabled;
        }
    },

    onError: function onErrorFn(error) {
        alert(error);
    },

    hideInfoBar: function hideInfoBarFn() {
        document.getElementById("infoBox").style.display = "none";
    },

    showInfoBar: function worldLoadedFn() {
        document.getElementById("infoBox").style.display = "table";
        document.getElementById("loadingMessage").style.display = "none";
    }
};

World.init();

 

Could you give me the structure or an simple example program that included all I need to this? Thank you


Regards,


Sarah.

Hi,


From what i can see in your code, the  World.createDescriptionDrawable(); function should be called before the  World.createTracker(); function. Additionally, the  cam:createDescriptionDrawable(objectData[i].description) should be replaced by  cam: World.drawables since the createDescriptionDrawable function is not returning any valid drawable. Make sure that the drawables you are creating are valid to be shown, because it won't show if they are not.


For more info take a look at:  https://www.wikitude.com/external/doc/documentation/latest/android/objecttracking.html#basic-object-tracking


Regards,


Aitor.

Hi, there i have the same problem like this. I have try it with online json hosting (the server) on this link : https://api.npoint.io/385a0e80d18cca44d8b3


and i have modify the code above to this code. about the createDescriptionDrawable() i just modify some code from the sample.

var ServerInformation = {
    OBJECTDATA_SERVER: "https://api.npoint.io/385a0e80d18cca44d8b3",
    OBJECTDATA_SERVER_ARG_NAME: "name",
    OBJECTDATA_SERVER_ARG_DESC: "description"
};

var World = {
    loaded: false,
    objectData: [],
    drawables: [],
    objectCenter: {
        x: 0,
        y: -0.14,
        z: 0
    },

    init: function initFn() {
        World.requestDataFromServer();
        World.createTracker();
        World.createDescriptionDrawable();
    },

    requestDataFromServer: function requestDataFromServerFn() {

        /* Set helper var to avoid requesting places while loading. */
        World.isRequestingData = true;
        World.updateStatusMessage('Requesting places from web-service');

        /* Server-url to JSON content provider. */
        var serverUrl = ServerInformation.OBJECTDATA_SERVER + "?" + ServerInformation.OBJECTDATA_SERVER_ARG_NAME + "=" +
            name + "&" + ServerInformation.OBJECTDATA_SERVER_ARG_DESC + "=" +
            description;

        var jqxhr = $.getJSON(serverUrl, function (data) {
                World.loadPoisFromJsonData(data);
            })
            .error(function (err) {
                World.updateStatusMessage("Invalid web-service response.", true);
                World.isRequestingData = false;
            })
            .complete(function () {
                World.isRequestingData = false;
            });
    },


    loadObjectsFromJsonData: function loadObjectsFromJsonDataFn(data) {
        for (var currentObjectNr = 0; currentObjectNr < data.length; currentObjectNr++) {
            var singleObject = {
                id: data[currentObjectNr].id,
                name: data[currentObjectNr].name,
                description: data[currentObjectNr].description,
                url: data[currentObjectNr].url
            };

            World.objectData.push(singleObject);
        }
    },

    createDescriptionDrawable: function createDescriptionDrawableFn() {
        var descDisctance = 0.2;

        var descObject = World.getCone(-descDisctance, +descDisctance);
        World.drawables.push(descObject);
    },

    getDescriptionDrawable: function getDescriptionDrawableFn(positionX, positionZ) {
        var descScale = 0.2;

        return new AR.Model(objectData.data.description, {
            scale: {
                x: descScale,
                y: descScale,
                z: descScale
            },
            translate: {
                x: positionX,
                y: World.objectCenter.y,
                z: positionZ
            },
            rotate: {
                x: -90
            },
            onError: World.onError
        });
    },


    createTracker: function createTrackerFn() {
        this.targetCollectionResource = new AR.TargetCollectionResource(objectData.data.url, {
            onError: World.onError
        });

        this.tracker = new AR.ObjectTracker(this.targetCollectionResource, {
            onError: World.onError
        });

        for (var i = 0; i < objectData.length; i++) {
            this.objectTrackable = new AR.ObjectTrackable(this.tracker, objectData[i].id, {
                drawables: {
                    cam: createDescriptionDrawable(objectData[i].description)
                },
                onObjectRecognized: World.objectRecognized,
                onObjectLost: World.objectLost,
                onError: World.onError
            });
        }
    },

    objectRecognized: function objectRecognizedFn() {
        World.hideInfoBar();
        World.setAugmentationsEnabled(true);
    },

    objectLost: function objectLostFn() {
        World.setAugmentationsEnabled(false);
    },

    setAugmentationsEnabled: function setAugmentationsEnabledFn(enabled) {
        for (var i = 0; i < World.drawables.length; i++) {
            World.drawables[i].enabled = enabled;
        }
    },

    onError: function onErrorFn(error) {
        alert(error);
    },

    hideInfoBar: function hideInfoBarFn() {
        document.getElementById("infoBox").style.display = "none";
    },

    showInfoBar: function worldLoadedFn() {
        document.getElementById("infoBox").style.display = "table";
        document.getElementById("loadingMessage").style.display = "none";
    }
};

World.init();

  

this is the index.html

 

<!DOCTYPE HTML>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta content="width=device-width,initial-scale=1,maximum-scale=5,user-scalable=yes" name="viewport">

    <!-- disables pinch-scaling of the webview, so that gestures only do what they're supposed to -->
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />

    <title></title>

    <script src="https://www.wikitude.com/libs/architect.js"></script>
    <script type="text/javascript" src="../ade.js"></script>

    <link rel="stylesheet" href="css/default.css">
</head>

<body>

    <script src="js/objectreak.js"></script>
</body>

</html>

 
after i scan the object it's did't show anything. I don;t know where is my mistake, can you help me?

Regards,

Riken

Hi,


From what i can see in your code, you are calling correctly the World.createTracker() in the init() function, but the objectData you are using does not exists. 


Another thing that i noticed is that the requestDataFromServer() function is not being called anywhere, so it would make sense that this is not working as the data is not requested.


One more thing i have to mention is that if you want to create object targets, I don't think you need a markerList, which is what you are using in the loadObjectsFromJsonData() function. Here, after calling the requestDataFromServer() method, i would fill the objectData variable (it should be declared outside), and then you would be able to use it in the createTracker() function.


var ServerInformation = {
    OBJECTDATA_SERVER: "https://.....",
    OBJECTDATA_SERVER_ARG_NAME: "nama_objek",
    OBJECTDATA_SERVER_ARG_DESC: "description"
};

var World = {
    loaded: false,
    objectData: [],
    drawables: [],

    init: function initFn() {
        World.requestDataFromServer();
        World.createTracker();
    },

    requestDataFromServer: function requestDataFromServerFn() {

            /* Set helper var to avoid requesting places while loading. */
            World.isRequestingData = true;
            World.updateStatusMessage('Requesting places from web-service');

            /* Server-url to JSON content provider. */
            var serverUrl = ServerInformation.OBJECTDATA_SERVER + "?" + ServerInformation.OBJECTDATA_SERVER_ARG_NAME + "=" +
                nama_objek + "&" + ServerInformation.OBJECTDATA_SERVER_ARG_DESC + "=" +
                description;

            var jqxhr = $.getJSON(serverUrl, function(data) {
                    World.loadPoisFromJsonData(data);
                })
                .error(function(err) {
                    World.updateStatusMessage("Invalid web-service response.", true);
                    World.isRequestingData = false;
                })
                .complete(function() {
                    World.isRequestingData = false;
                });
            },
    },

    loadObjectsFromJsonData: function loadObjectsFromJsonDataFn(data) {
            for (var currentObjectNr = 0; currentObjectNr < data.length; currentObjectNr++) {
                var singleObject = {
                    "id": data[currentObjectNr].id,
                    "nama_objek": data[currentObjectNr].nama_objek,
                    "description": data[currentObjectNr].description
                };

                World.objectData.push(singleObject);
            }
    },

    createTracker: function createTrackerFn() {
        this.targetCollectionResource = new AR.TargetCollectionResource("https://...../file_name.wto", {
            onError: World.onError
        });

        this.tracker = new AR.ObjectTracker(this.targetCollectionResource, {
            onError: World.onError
        });

        for (var i = 0; i < objectData.length; i++) {
                this.objectTrackable = new AR.ObjectTrackable(this.tracker, objectData[i].id, {
                    drawables: {
                        cam: createDescriptionDrawable(objectData[i].description,
                    },
                    onObjectRecognized: World.objectRecognized,
                    onObjectLost: World.objectLost,
                    onError: World.onError
                });
        }
    },

    objectRecognized: function objectRecognizedFn() {
        World.hideInfoBar();
        World.setAugmentationsEnabled(true);
    },

    objectLost: function objectLostFn() {
        World.setAugmentationsEnabled(false);
    },

    setAugmentationsEnabled: function setAugmentationsEnabledFn(enabled) {
        for (var i = 0; i < World.drawables.length; i++) {
            World.drawables[i].enabled = enabled;
        }
    },

    onError: function onErrorFn(error) {
        alert(error);
    },

    hideInfoBar: function hideInfoBarFn() {
        document.getElementById("infoBox").style.display = "none";
    },

    showInfoBar: function worldLoadedFn() {
        document.getElementById("infoBox").style.display = "table";
        document.getElementById("loadingMessage").style.display = "none";
    }
};

World.init();


I send you your code with some modifications. Hopefully it would make it clear for you. I did not see the createDescriptionDrawable() function anywhere but i assume you have it in other place.


Regards,


Aitor.

Hi Aitor,

this is my code in javascript, can you check it where actually my mistake is?


var ServerInformation = {
    OBJECTDATA_SERVER: "https://.....",
    OBJECTDATA_SERVER_ARG_NAME: "nama_objek",
    OBJECTDATA_SERVER_ARG_DESC: "description"
};

var World = {
    loaded: false,
    drawables: [],

    init: function initFn() {
        World.createTracker();
    },

    requestDataFromServer: function requestDataFromServerFn(nama_objek, description) {

            /* Set helper var to avoid requesting places while loading. */
            World.isRequestingData = true;
            World.updateStatusMessage('Requesting places from web-service');

            /* Server-url to JSON content provider. */
            var serverUrl = ServerInformation.OBJECTDATA_SERVER + "?" + ServerInformation.OBJECTDATA_SERVER_ARG_NAME + "=" +
                nama_objek + "&" + ServerInformation.OBJECTDATA_SERVER_ARG_DESC + "=" +
                description;

            var jqxhr = $.getJSON(serverUrl, function(data) {
                    World.loadPoisFromJsonData(data);
                })
                .error(function(err) {
                    World.updateStatusMessage("Invalid web-service response.", true);
                    World.isRequestingData = false;
                })
                .complete(function() {
                    World.isRequestingData = false;
                });
            },
    },

    loadObjectsFromJsonData: function loadObjectsFromJsonDataFn(objectData) {

            /* Loop through Object-information and create an AR.Object (=Marker) per Object. */
            for (var currentObjectNr = 0; currentObjectNr < objectData.length; currentObjectNr++) {
                var singleObject = {
                    "id": objectData[currentObjectNr].id,
                    "nama_objek": objectData[currentObjectNr].nama_objek,
                    "description": objectData[currentObjectNr].description
                };

                World.markerList.push(new Marker(singleObject));
            }
    },

    createTracker: function createTrackerFn() {
        this.targetCollectionResource = new AR.TargetCollectionResource("https://...../file_name.wto", {
            onError: World.onError
        });

        this.tracker = new AR.ObjectTracker(this.targetCollectionResource, {
            onError: World.onError
        });

        for (var i = 0; i < objectData.length; i++) {
                this.objectTrackable = new AR.ObjectTrackable(this.tracker, objectData[i].id, {
                    drawables: {
                        cam: createDescriptionDrawable(objectData[i].description,
                    },
                    onObjectRecognized: World.objectRecognized,
                    onObjectLost: World.objectLost,
                    onError: World.onError
                });
        }
    },

    objectRecognized: function objectRecognizedFn() {
        World.hideInfoBar();
        World.setAugmentationsEnabled(true);
    },

    objectLost: function objectLostFn() {
        World.setAugmentationsEnabled(false);
    },

    setAugmentationsEnabled: function setAugmentationsEnabledFn(enabled) {
        for (var i = 0; i < World.drawables.length; i++) {
            World.drawables[i].enabled = enabled;
        }
    },

    onError: function onErrorFn(error) {
        alert(error);
    },

    hideInfoBar: function hideInfoBarFn() {
        document.getElementById("infoBox").style.display = "none";
    },

    showInfoBar: function worldLoadedFn() {
        document.getElementById("infoBox").style.display = "table";
        document.getElementById("loadingMessage").style.display = "none";
    }
};

World.init();

 

Thankyou

Regards,


Sarah.


Hi Aitor, Sorry, I think there's missunderstanding, I mean .json link in this case is for the ObjectTracking, which is contain the name and the description of the object to iterate. The code for my ObjectTracking project (for get the .json data) is the same code like in the POI example, I copy and modify it. For my POI project it successfully working. But, in my ObjectTracking project is not working, the name and the description is not showing. Thankyou. Regards, Sarah.

Hi,


Could you please send me you javascript so i can check how are you using our SDK?


In our samples, the request is being called like:


requestDataFromServer: function requestDataFromServerFn(lat, lon) {

        /* Set helper var to avoid requesting places while loading. */
        World.isRequestingData = true;
        World.updateStatusMessage('Requesting places from web-service');

        /* Server-url to JSON content provider. */
        var serverUrl = ServerInformation.POIDATA_SERVER + "?" + ServerInformation.POIDATA_SERVER_ARG_LAT + "=" +
            lat + "&" + ServerInformation.POIDATA_SERVER_ARG_LON + "=" +
            lon + "&" + ServerInformation.POIDATA_SERVER_ARG_NR_POIS + "=20";

        var jqxhr = $.getJSON(serverUrl, function(data) {
                World.loadPoisFromJsonData(data);
            })
            .error(function(err) {
                World.updateStatusMessage("Invalid web-service response.", true);
                World.isRequestingData = false;
            })
            .complete(function() {
                World.isRequestingData = false;
            });
},


The $.getJSON is the method we are calling with our testing url from the server. Did you check if the data variable is not empty? In case it is empty, the problem is coming from your webservice, in case is not empty, maybe the data you are sending is not the same that the data we require and you should take a look at the samples/documentation to see what data do we need.


Regards,


Aitor.

Hi Aitor, Thankyou for your reply, but I don't really understand where should I put the .json link (because it's also from webservice), in my javascript code. I've tried the same code like in the POI Wikitude example project to get the .json link of the latitude and longitude, but it doesn't work, nothing happen and nothing appear. Could you give me an example code how to get the .json link in my javascript code before I iterate it? I'm so sorry for making this become so difficult, because all of it is really new for me, but i must to finish it soon. Thankyou. Regards, Sarah.

Hi Sarah,


For the .wto file you are right you should put the link on the TargetCollectionResource. For the .json file we don't provide anything to handle it, so it should be handled by yourself. This could be an example:


this.targetCollectionResource = new AR.TargetCollectionResource("file_name.wto", {
            onError: World.onError
        });

        this.tracker = new AR.ObjectTracker(this.targetCollectionResource, {
            onError: World.onError
        });

for (var i = 0; i < jsonItems.length; i++) {
        this.objectTrackable = new AR.ObjectTrackable(this.tracker, jsonItems[i].itemId, {
            drawables: {
                cam: createDescriptionDrawable(jsonItems[i].description,
            },
            onObjectRecognized: World.objectRecognized,
            onObjectLost: World.objectLost,
            onError: World.onError
        });
}


The previous code i sent is a modification of the SimpleObjectTracking sample that is in the example project we provide:  https://www.wikitude.com/download-wikitude-sdk-for-android/. The difference is, after you get the .json file in the javascript code, you can iterate it and create different objectTrackables depending of the id that it should be tracking from the .wto file. Once you know which item you have, you can add a drawable from it (in this case the description).


Regards,


Aitor.

Hi, I know generaly what I sould do, but I don't really understand how to implement that condition into my code. Could you give me an example code based on that condition? For the .wto files I just need to put my link on the TargetCollectionResource, right? but for the .json files where sould I put the link? and how to iterate it on javascript? I'm sorry because I really new in this. Thank you Regards, Sarah.

Hi,


As you mentioned previously, you have a .wto file uploaded to a web service which is updated everytime you need to add some objects. In the same way, you could have a .json file uploaded to a web service that contains the list of the targets and their descriptions. Once both are downloaded, you just need to iterate the .json file, and for every item that exists, create an ObjectTrackable in the same way we are doing in the Wikitude Sample app, attaching the description that is in the .json file.


Regards,


Aitor.

Hi Aitor,


Thanks fot the solution that could be possible to do. But I don't really understand how to do this statement 


"In your code, you could download the .wto + the json files and iterate through it, adding an ObjectTrackable for each item"


Could you hep me with an example what should I do and where should I put my code in Android Studio or javascript file? I really need your help.

Thank You


Regards,

Sarah.

Hi Sarah,


We don't provide that kind of service by our own, but it could be possible if alongside you .wto file, you have another file (a json for example) which lists the targets and their descriptions. In your code, you could download the .wto + the json files and iterate through it, adding an ObjectTrackable for each item.


Regards,


Aitor.

Hi, Aitor Thanks for the answer, but I'm sorry I think you don't get what I mean. Based on your explanation, all of my object target must be declared on the code. So, everytime I add the new object target, I need to modify my code too. But in my case, I need the code that don't need to modify everytime I add more object on my target collection. It means like my code automatically know that there's a new object, without I'm telling it. Most likely the cloud recognition. I really need to know is that possible to do something like that? Thanks Regards, Sarah
Login or Signup to post a comment