Hi,
I'll ask you several questions in order to find an answer:
Best regards,
Aitor.
Hi again,
Also, everything is working as it should be like radar and markers ... But Distance is not updating so the same markers are always rendered on the screen..
// information about server communication. This sample webservice is provided by Wikitude and returns random dummy places near given location /*var ServerInformation = { POIDATA_SERVER: "https://fesar.000webhostapp.com/gpsdata.json", POIDATA_SERVER_ARG_LAT: "lat", POIDATA_SERVER_ARG_LON: "lon", POIDATA_SERVER_ARG_NR_POIS: "nrPois" };*/ // implementation of AR-Experience (aka "World") var World = { //var listId, // user's latest known location, accessible via userLocation.latitude, userLocation.longitude, userLocation.altitude userLocation: null, // you may request new data from server periodically, however: in this sample data is only requested once //isRequestingData: false, // true once data was fetched //initiallyLoadedData: false, // different POI-Marker assets markerDrawable_idle: null, markerDrawable_selected: null, markerDrawable_directionIndicator: null, // list of AR.GeoObjects that are currently shown in the scene / World markerList: [], // The last selected marker currentMarker: null, locationUpdateCounter: 0, updatePlacemarkDistancesEveryXLocationUpdates: 1, // called to inject new POI data loadPoisFromJsonData: function loadPoisFromJsonDataFn(poiData) { // show radar & set click-listener PoiRadar.show(); $('#radarContainer').unbind('click'); $("#radarContainer").click(PoiRadar.clickedRadar); // empty list of visible markers World.markerList.forEach(marker => { marker.markerObject.destroy(); }); World.markerList = []; // start loading marker assets /*World.markerDrawable_idle = new AR.ImageResource("assets/marker_idle.png"); World.markerDrawable_selected = new AR.ImageResource("assets/marker_selected.png");*/ World.markerImageRessources = {"idle": {}, "selected": {}}; World.markerImageRessources.idle["transport"] = new AR.ImageResource("assets/logi_idle.png"); World.markerImageRessources.selected["transport"] = new AR.ImageResource("assets/logi_selected.png"); World.markerImageRessources.idle["medersa"] = new AR.ImageResource("assets/medersa_idle.png"); World.markerImageRessources.selected["medersa"] = new AR.ImageResource("assets/medersa_selected.png"); World.markerImageRessources.idle["mosquee"] = new AR.ImageResource("assets/mosquee_idle.png"); World.markerImageRessources.selected["mosquee"] = new AR.ImageResource("assets/mosquee_selected.png"); World.markerImageRessources.idle["bab"] = new AR.ImageResource("assets/bab_idle.png"); World.markerImageRessources.selected["bab"] = new AR.ImageResource("assets/bab_selected.png"); World.markerImageRessources.idle["borj"] = new AR.ImageResource("assets/borj_idle.png"); World.markerImageRessources.selected["borj"] = new AR.ImageResource("assets/borj_selected.png"); World.markerImageRessources.idle["autre"] = new AR.ImageResource("assets/others_idle.png"); World.markerImageRessources.selected["autre"] = new AR.ImageResource("assets/others_selected.png"); World.markerImageRessources.idle["fondouk"] = new AR.ImageResource("assets/fondouk_idle.png"); World.markerImageRessources.selected["fondouk"] = new AR.ImageResource("assets/fondouk_selected.png"); World.markerImageRessources.idle["mausoleum"] = new AR.ImageResource("assets/mausoleum_idle.png"); World.markerImageRessources.selected["mausoleum"] = new AR.ImageResource("assets/mausoleum_selected.png"); World.markerDrawable_directionIndicator = new AR.ImageResource("assets/indi.png"); // loop through POI-information and create an AR.GeoObject (=Marker) per POI for (var currentPlaceNr = 0; currentPlaceNr < poiData.length; currentPlaceNr++) { var singlePoi = { "id": poiData[currentPlaceNr].id, "latitude": parseFloat(poiData[currentPlaceNr].latitude), "longitude": parseFloat(poiData[currentPlaceNr].longitude), "altitude": parseFloat(poiData[currentPlaceNr].altitude), "title": poiData[currentPlaceNr].name, "description": poiData[currentPlaceNr].description, "type": poiData[currentPlaceNr].type, "pic" : poiData[currentPlaceNr].pic }; World.markerList.push(new Marker(singlePoi)); AR.logger.debug(singlePoi.title+' added ! '); } // updates distance information of all placemarks World.updateDistanceToUserValues(); World.updateStatusMessage(currentPlaceNr + ' places loaded'); // set distance slider to 100% $("#panel-distance-range").val(100); $("#panel-distance-range").slider("refresh"); }, // sets/updates distances of all makers so they are available way faster than calling (time-consuming) distanceToUser() method all the time updateDistanceToUserValues: function updateDistanceToUserValuesFn() { for (var i = 0; i < World.markerList.length; i++) { World.markerList[i].distanceToUser = World.markerList[i].markerObject.locations[0].distanceToUser(); } }, // updates status message shown in small "i"-button aligned bottom center updateStatusMessage: function updateStatusMessageFn(message, isWarning) { var themeToUse = isWarning ? "e" : "c"; var iconToUse = isWarning ? "alert" : "info"; $("#status-message").html(message); $("#popupInfoButton").buttonMarkup({ theme: themeToUse, icon: iconToUse }); }, // location updates, fired every time you call architectView.setLocation() in native environment locationChanged: function locationChangedFn(lat, lon, alt, acc) { // store user's current location in World.userLocation, so you always know where user is World.userLocation = { 'latitude': lat, 'longitude': lon, 'altitude': alt, 'accuracy': acc }; // request data if not already present if (!World.initiallyLoadedData) { //World.requestDataFromServer(lat, lon); World.requestDataFromLocal(lat, lon); World.initiallyLoadedData = true; } else if (World.locationUpdateCounter === 0) { // update placemark distance information frequently, you max also update distances only every 10m with some more effort World.updateDistanceToUserValues(); } // helper used to update placemark information every now and then (e.g. every 10 location upadtes fired) World.locationUpdateCounter = (++World.locationUpdateCounter % World.updatePlacemarkDistancesEveryXLocationUpdates); }, // fired when user pressed maker in camera onMarkerSelected: function onMarkerSelectedFn(marker) { World.currentMarker = marker; // update panel values /*$("#poi-detail-title").html(marker.poiData.title); $("#poi-detail-image").html("<img src='" + marker.poiData.pic + "' class='pic'/>"); $("#poi-detail-description").html(marker.poiData.description);*/ // It's ok for AR.Location subclass objects to return a distance of `undefined`. In case such a distance was calculated when all distances were queried in `updateDistanceToUserValues`, we recalcualte this specific distance before we update the UI. if( undefined === marker.distanceToUser ) { marker.distanceToUser = marker.markerObject.locations[0].distanceToUser(); } var distanceToUserValue = (marker.distanceToUser > 999) ? ((marker.distanceToUser / 1000).toFixed(2) + " km") : (Math.round(marker.distanceToUser) + " m"); AR.platform.sendJSONObject({title: marker.poiData.title, type: marker.poiData.type, description: marker.poiData.description, distance: distanceToUserValue, images: marker.poiData.pic }); /*$("#poi-detail-distance").html(distanceToUserValue); // show panel $("#panel-poidetail").panel("open", 123); $( ".ui-panel-dismiss" ).unbind("mousedown"); $("#panel-poidetail").on("panelbeforeclose", function(event, ui) { World.currentMarker.setDeselected(World.currentMarker); // ### laisser le merker selectionné apres avoir fermer le panel !!! }); */ }, // screen was clicked but no geo-object was hit onScreenClick: function onScreenClickFn() { // you may handle clicks on empty AR space too //alert('Your : \n'+' longitude = '+World.userLocation.longitude+' \nlatitude = '+World.userLocation.latitude+' \naltitude = '+World.userLocation.altitude+' \naccuracy = '+World.userLocation.accuracy); }, // tell native (urlListener) that user pressed 'Snapshot' button captureScreen: function captureScreenFn() { AR.platform.sendJSONObject({ name: "button", action: "captureScreen" }); }, // returns distance in meters of placemark with maxdistance * 1.1 getMaxDistance: function getMaxDistanceFn() { // sort places by distance so the first entry is the one with the maximum distance World.markerList.sort(World.sortByDistanceSortingDescending); // use distanceToUser to get max-distance var maxDistanceMeters = World.markerList[0].distanceToUser; // return maximum distance times some factor >1.0 so ther is some room left and small movements of user don't cause places far away to disappear return maxDistanceMeters * 1.1; }, // udpates values show in "range panel" updateRangeValues: function updateRangeValuesFn() { // get current slider value (0..100); var slider_value = $("#panel-distance-range").val(); // max range relative to the maximum distance of all visible places var maxRangeMeters = Math.round(World.getMaxDistance() * (slider_value / 100)); // range in meters including metric m/km var maxRangeValue = (maxRangeMeters > 999) ? ((maxRangeMeters / 1000).toFixed(2) + " km") : (Math.round(maxRangeMeters) + " m"); // number of places within max-range var placesInRange = World.getNumberOfVisiblePlacesInRange(maxRangeMeters); // update UI labels accordingly $("#panel-distance-value").html(maxRangeValue); $("#panel-distance-places").html((placesInRange !== 1) ? (placesInRange + " Places") : (placesInRange + " Place")); // update culling distance, so only places within given range are rendered AR.context.scene.cullingDistance = Math.max(maxRangeMeters, 1); // update radar's maxDistance so radius of radar is updated too PoiRadar.setMaxDistance(Math.max(maxRangeMeters, 1)); }, // returns number of places with same or lower distance than given range getNumberOfVisiblePlacesInRange: function getNumberOfVisiblePlacesInRangeFn(maxRangeMeters) { // sort markers by distance World.markerList.sort(World.sortByDistanceSorting); // loop through list and stop once a placemark is out of range ( -> very basic implementation ) for (var i = 0; i < World.markerList.length; i++) { if (World.markerList[i].distanceToUser > maxRangeMeters) { return i; } } // in case no placemark is out of range -> all are visible return World.markerList.length; }, handlePanelMovements: function handlePanelMovementsFn() { $("#panel-distance").on("panelclose", function(event, ui) { $("#radarContainer").addClass("radarContainer_left"); $("#radarContainer").removeClass("radarContainer_right"); PoiRadar.updatePosition(); }); $("#panel-distance").on("panelopen", function(event, ui) { $("#radarContainer").removeClass("radarContainer_left"); $("#radarContainer").addClass("radarContainer_right"); PoiRadar.updatePosition(); }); }, // display range slider showRange: function showRangeFn() { if (World.markerList.length > 0) { // update labels on every range movement $('#panel-distance-range').change(function() { World.updateRangeValues(); }); World.updateRangeValues(); World.handlePanelMovements(); // open panel $("#panel-distance").trigger("updatelayout"); $("#panel-distance").panel("open", 1234); } else { // no places are visible, because the are not loaded yet World.updateStatusMessage('No places available yet', true); } }, // request POI data requestDataFromLocal: function (centerPointLatitude, centerPointLongitude) { $(document).on('click', '#myList li', function() { let listerId = $(this).attr('id'); switch(listerId) { case "mosquee": World.loadPoisFromJsonData(Masjid); break; case "bab": World.loadPoisFromJsonData(Babs); break; case "fondouk": World.loadPoisFromJsonData(Fondok); break; case "borj": World.loadPoisFromJsonData(burjs); break; case "medersa": World.loadPoisFromJsonData(medersas); break; case "transport": World.loadPoisFromJsonData(transport); break; case "autre": World.loadPoisFromJsonData(Others); break; case "mausoleum": World.loadPoisFromJsonData(mausoleum); break; case "all": World.loadPoisFromJsonData(GpsData); break; } }); World.loadPoisFromJsonData(GpsData); }, /*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; }); },*/ // helper to sort places by distance sortByDistanceSorting: function(a, b) { return a.distanceToUser - b.distanceToUser; }, // helper to sort places by distance, descending sortByDistanceSortingDescending: function(a, b) { return b.distanceToUser - a.distanceToUser; } }; /* forward locationChanges to custom function */ AR.context.onLocationChanged = World.locationChanged; /* forward clicks in empty area to World */ AR.context.onScreenClick = World.onScreenClick; AR.context.scene.maxScalingDistance = 100000; AR.context.scene.minScalingDistance = 10; AR.context.scene.cullingDistance = 10000; AR.radar.notifyUpdateRadarPosition();
Hi,
After putting some logs in the locationChanged callback and testing with 2 devices: Huawei P30 and Pixel 3A XL, I can see that the callback is being called several times in our limitingrange sample (whenever the location from the device is changing) and the distance is also changed.
As I'm unable to reproduce your issue my suggestion would be to update to our latest 9.10 version located in https://www.wikitude.com/download-wikitude-sdk-for-android/ to see if the issue is still happening. If you still have the same problem, I would need you to send a working sample that includes not only the .js file but also the .html, .css and the assets to make it work properly.
Best regards,
Aitor.
Hi again Aitor,
So i changed to the 9.10 version as you proposed ( by replacing the library .aar), but unfortunately, the distance is not updating in real-time, it takes almost 2 minutes to update inside my description Panel (made with Java), and on the marker (i added a distance label).
I've attached the asset file named "fes", you will find all the files inside.
I really appreciate any good feedback, because I'm doing a scientific study paper based on your A.R tool ONLY.
The users need to navigate between very close monuments ( 10 meters distance separating two monuments), that's why i need the distance to update in real-time so that markers can change locations simultaneously.
Best regards.
Moha
Hi,
I've checked your sample and I can confirm that the locationChanged() method is called more than once in all the device I'm testing with. Is the GPS of your device working fine? Do you have the high accuracy gps enabled? Is your position being updated properly in other applications like Google Maps?
Best regards,
Aitor.
Hi,
After putting some logs in the locationChanged callback and testing with 2 devices: Huawei P30 and Pixel 3A XL, I can see that the callback is being called several times in our limitingrange sample (whenever the location from the device is changing) and the distance is also changed.
As I'm unable to reproduce your issue my suggestion would be to update to our latest 9.10 version located in https://www.wikitude.com/download-wikitude-sdk-for-android/cookie clicker to see if the issue is still happening. If you still have the same problem, I would need you to send a working sample that includes not only the .js file but also the .html, .css and the assets to make it work properly.
Best regards,
Aitor.
I have updated to the latest version but the problem is still the same, it seems that the file is corrupted.
Hello Aitor,
So, i tested my Gps location on my phone (Pocophone X3 Pro, Xiaomi) and it's working fine and the accuracy is very high.
I also tested the application on other phones and it's the same case, the distance is not updating, so the markers on the screen.
Only one mobile worked well, and the application is working perfectly on: SONY XPERIA L2.
is it a compatibility issue?
- One last thing, I want to show the distance on my marker, so I created a distance label and worked, but it doesn't update in real-time, how can I pass the updated value of the distance?
Best regards
Hi,
If the sample is working fine in some devices, I would say it seems like a device specific issue. I'll check with our QA if we have some xiaomi devices to test thoroughly this issue.
Regarding the distance, it is updated everytime the locationChanged() method is called which triggers the updateDistanceToUserValues() -> distanceToUser() calls. Once the distanceToUser is updated, you could create your own method in the marker js file to modify the value in the new label.
Best regards,
Aitor.
Mohamed.zaifri1
Hello Wikitude,
I have started a project 3 years ago with Javascript SDK 6, now I migrated to JS SDK 8.4.0 and i only changed the library file (.aar) in my project while i kept everything as well as i kept the sample file i used to design my app.
the application is working fine but the distance is not updating in real-time, actually, it doesn't update at all unless i close the app and return after an hour or more. i suspected that i have forgot to add some file to my new project. can you provide some help with this migration?
I'm working in ANDROID ios. The sample file i used is : "10_BrowsingPois_3_LimitingRange".
Thanks.